英文:
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<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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论