【发布时间】:2022-12-23 05:15:59
【问题描述】:
我正在开发具有下载文件功能的 asp.net 核心应用程序。使用此功能,我们可以创建多个下载任务并使用Task.Whenall 一次执行它们。
我正在尝试实现取消下载功能,使用该功能我们可以通过单击我的剃刀页面之一上的取消按钮来中止/取消完整的下载操作(如果我选择了 100 个要下载的文件并在下载 10 个文件后单击取消,则剩余 90 个文件应该不能下载)。
目前无法取消,一旦下载操作开始,即使我们关闭下载页面,它也会在后台继续执行,除非所有文件下载失败/成功。退出应用程序会停止它。
实现如下。
下载控制器类:
//variable declaration
CancellationTokenSource cts;
[HttpPost]
public async Task<IActionResult> Download_iles(DownloadFilesModel downloadFilesModel)
{
cts=new CancellationTokenSource();
var successFiles = await _downloadManager.DownloadAsyncpa(downloadFilesModel.param1, downloadFilesModel.param2, cts.Token);
}
管理文件下载类:
public class ManageFileDownlods : BackgroundService, IManageFileDownlods
{
//Constructor
public ManageFileDownlods(IDownloadmaster downloadmaster)
{
_downloadmaster = downloadmaster;
}
public async Task<List<DownloadFile>>
DownloadAsync (funcparam1,funcparam2,CancellationToken cancellationToken=default)
{
// For each server in serverQueue these multiple tasks will execure
while (serverQueue.Count > 0)
{
//Multiple tasks created to downloadfiles
downloadTasksList.Add(ServerProcess(funcparam1, funcparam2, cancellationToken));
//Multiple tasks executed here to download files
try
{
await Task.WhenAll(downloadTasksList.ToArray());
}
catch()
{ }
}
}
private async Task<List<DownloadFile>> ServerProcess (funcparam1, funcparam2,
CancellationToken cancellationToken)
{
while (funcparam1.Count > 0)
{
//5 taks created in loop
for (int i = 0; i < 5; i++)
{
//Multiple tasks created to downloadfiles
fileDownlodTasks.Add(_downloadmaster.Download(param1, param2,
cancellationToken));
await Task.Delay(300);
}
try
{
//Multiple tasks executed here to download files
await Task.WhenAll(fileDownlodTasks.ToArray());
}
catch (TaskCanceledException ex)
{
Debug.WriteLine("execution stopped");
throw ex;
}
}
}
}
下载大师班:
public async Task<DownloadFile> Download (param1,param2,CancellationToken cancellationToken)
{
//actual function which initiated file download from server
var filecontents = DownloadFileFromServer (param1,param2, cancellationToken);
}
我在互联网上花了很多时间,浏览了很多关于取消任务的不同文章,尝试实施这些文章中给出的多种方法,但无法取消操作。
【问题讨论】:
-
这与您的问题无关,但它肯定需要修复:永远不要执行
throw ex;,其中ex是捕获的异常。您将丢失堆栈跟踪,使调试更加困难。相反,只需执行throw;即可正确保留堆栈跟踪。 -
您创建了自己的取消令牌源 - 这意味着您需要对其调用取消才能取消它。与其制作您自己的取消令牌源,不如从操作方法参数中获取取消令牌可能更好。
-
请发布一个最小的、可重现的例子。要正确取消,
cts需要在某个时候取消和DownloadFileFromServer方法必须遵守取消。 -
Stephen Cleary,你的意思是 cts.Cancel() 方法应该在 DownloadFileFromServer() 方法中的某个地方?我在控制器操作方法中初始化了 Cancellationtokensoiurce。并将令牌传递给服务。那是对的吗 ?还是应该在 Downloadmaster 类中初始化 Cancellationtokensoiurce?
-
梅森,正如您在代码 sn-p 中看到的那样,我将令牌作为参数从控制器方法传递到服务方法,依此类推到主要的 Downloadfilefromserver 方法。这不是正确的做法吗?
标签: asp.net-core task background-service cancellationtokensource cancellation-token