停止在ASP.NET Core中进行的下载。

huangapple go评论62阅读模式
英文:

Stop a download in progress in ASP.NET Core

问题

如果我想在不损坏.flv文件流的情况下中断下载,我该如何做呢?考虑到可能会同时进行多个下载,所以我不想一次中断它们所有。

这是我下载文件的方式:

app.MapGet("/stream", async context =>
{
    var httpClient = new HttpClient();

    var request = new HttpRequestMessage(HttpMethod.Get, url);
    var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);

    context.Response.ContentType = "application/octet-stream";
    context.Response.Headers.Add("Content-Disposition", "attachment; filename=\"file.flv\"");
    context.Response.Headers.Add("Transfer-Encoding", "chunked");

    using var responseStream = await response.Content.ReadAsStreamAsync();
    await responseStream.CopyToAsync(context.Response.Body);
});

app.MapGet("/stop", async context =>
{
    await context.Response.WriteAsync("Download stopped.");
    // 我该如何停止下载??????
});
英文:

If I wanted to interrupt the download without corrupting the .flv file stream, how could I do that? Considering that there might be multiple downloads at the same time, so I don't want to interrupt them all at once.

Here is how I download the file:

app.MapGet("/stream", async context =>
{
    var httpClient = new HttpClient();

    var request = new HttpRequestMessage(HttpMethod.Get, url);
    var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);

    context.Response.ContentType = "application/octet-stream";
    context.Response.Headers.Add("Content-Disposition", "attachment; filename=\"file.flv\"");
    context.Response.Headers.Add("Transfer-Encoding", "chunked");

    using var responseStream = await 
    response.Content.ReadAsStreamAsync();
    await responseStream.CopyToAsync(context.Response.Body);
});

app.MapGet("/stop", async context =>
{
    await context.Response.WriteAsync("Download stopped.");
    // How do I stop?????????
});

答案1

得分: 1

I see the option of implementing that through CancellationTokenSource, you need to keep reference to every download you start, so you can abort it in different request.

var builder = WebApplication.CreateBuilder(args);

var app = builder.Build();

app.UseHttpsRedirection();

var cancellationTokens = new Dictionary<string, CancellationTokenSource>();

app.MapGet("/stream", async context =>
{
    var id = context.Request.Query["id"];
    var cts = new CancellationTokenSource();
    cancellationTokens[id] = cts;

    var httpClient = new HttpClient();

    var request = new HttpRequestMessage(HttpMethod.Get, "https://filesamples.com/samples/video/flv/sample_1280x720_surfing_with_audio.flv");
    var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cts.Token);

    context.Response.ContentType = "application/octet-stream";
    context.Response.Headers.Add("Content-Disposition", "attachment; filename=\"file.flv\"");
    context.Response.Headers.Add("Transfer-Encoding", "chunked");

    using var responseStream = await response.Content.ReadAsStreamAsync(cts.Token);

    await responseStream.CopyToAsync(context.Response.Body, cts.Token);
});

app.MapGet("/stop", async context =>
{
    var id = context.Request.Query["id"];

    cancellationTokens[id].Cancel();

    await context.Response.WriteAsync("Download stopped.");
});

app.Run();

Call to stop endpoint produces following stacktrace in console indicating that cancellation is done inside of CopyToAsync method. I also pass the same token in all methods that accept it.

英文:

I see the option of implementing that through CancellationTokenSource, you need to keep reference to every download you start, so you can abort it in different request.

var builder = WebApplication.CreateBuilder(args);

var app = builder.Build();

app.UseHttpsRedirection();

var cancellationTokens = new Dictionary&lt;string, CancellationTokenSource&gt;();

app.MapGet(&quot;/stream&quot;, async context =&gt;
{
    var id = context.Request.Query[&quot;id&quot;];
    var cts = new CancellationTokenSource();
    cancellationTokens[id] = cts;

    var httpClient = new HttpClient();

    var request = new HttpRequestMessage(HttpMethod.Get, &quot;https://filesamples.com/samples/video/flv/sample_1280x720_surfing_with_audio.flv&quot;);
    var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cts.Token);
    
    context.Response.ContentType = &quot;application/octet-stream&quot;;
    context.Response.Headers.Add(&quot;Content-Disposition&quot;, &quot;attachment; filename=\&quot;file.flv\&quot;&quot;);
    context.Response.Headers.Add(&quot;Transfer-Encoding&quot;, &quot;chunked&quot;);

    using var responseStream = await response.Content.ReadAsStreamAsync(cts.Token);

    await responseStream.CopyToAsync(context.Response.Body, cts.Token);
});

app.MapGet(&quot;/stop&quot;, async context =&gt;
{
    var id = context.Request.Query[&quot;id&quot;];

    cancellationTokens[id].Cancel();

    await context.Response.WriteAsync(&quot;Download stopped.&quot;);
});

app.Run();

Call to stop endpoint produces following stacktrace in console indicating that cancellation is done inside of CopyToAsync method. I also pass the same token in all methods that accept it

停止在ASP.NET Core中进行的下载。

huangapple
  • 本文由 发表于 2023年5月11日 00:17:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/76220630.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定