我无法停止创建的任务以下代码将不会发生
ts?.Cancel();
这就是我运行任务的方式
ts = new CancellationTokenSource();
await ((ViewModel)DataContext).loadTitles(progressTitle, ts.Token, prg);
和在视图模型中
public async Task loadTitles(IProgress<int> progress, CancellationToken ct, ProgressBar prg)
{
if (!ct.IsCancellationRequested)
{
foreach (var line in System.IO.Directory.EnumerateFiles(GlobalData.Config.DataPath, "*.jpg", SearchOption.AllDirectories))
{
mprogress += 1;
progress.Report((mprogress * 100 / totalFiles));
var item = ShellFile.FromFilePath(line);
ArtistNames.Add(new ArtistData
{
Name = item.Properties.System.Title.Value,
Tag = line
});
await Task.Delay(5);
}
}
}
对于其他四个功能,我编写了与同一功能相似的代码,并且任务已很好地停止,但是该功能无法正常工作。
答案 0 :(得分:1)
您无法停止您的任务,因为在loadTitle
方法的开始处,您检查是否请求取消。但这不是,也可能不是,因为您立即进入了foreach
循环。您需要在循环中检查它:
public async Task loadTitles(IProgress<int> progress, CancellationToken ct, ProgressBar prg)
{
foreach (var line in System.IO.Directory.EnumerateFiles(GlobalData.Config.DataPath, "*.jpg", SearchOption.AllDirectories))
{
if (ct.IsCancellationRequested)
{
break;
}
// ... the rest of your code
}
}
答案 1 :(得分:1)
除了第一行之外,没有其他方法可以监听CancellationToken
。
如果要实现正常取消,请在循环内测试令牌并将其传递给Task.Delay
。
请注意,如果loadTitles
是从UI线程中调用的,则它大多在同一UI线程中运行,因为这里除了Task.Delay
之外没有任何异步方法,它保留了调用者上下文并在UI中继续执行异步方法线。为避免这种情况,您需要在ConfigureAwait(false)
之后调用Task.Delay
。