简体   繁体   English

取消所有正在运行的任务

[英]Cancel All Running Task

I can not stop the created task The following code will not happen我不能停止创建的任务下面的代码不会发生

ts?.Cancel();

and this is how i run task这就是我运行任务的方式

ts = new CancellationTokenSource();
await ((ViewModel)DataContext).loadTitles(progressTitle, ts.Token, prg);

and in viewmodel并在视图模型中

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);
            }
        }

        }

I've written similar to the same function for four other functions, and the tasks are stopped well, but this one does not work.我已经为其他四个函数编写了类似相同的函数,并且任务停止得很好,但是这个不起作用。

You can't stop your tasks because at the very begininnig of loadTitle method you check whether the cancellation was requested.您无法停止您的任务,因为在loadTitle方法的最开始您会检查是否请求取消。 But it wasn't and can't be because you immediately step into a foreach loop.但这不是也不可能是因为您立即进入了foreach循环。 You need to check it inside of aa loop:您需要在 aa 循环内检查它:

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
    }
}

There's nothing listening to CancellationToken inside your method, except the first line.除了第一行之外,您的方法中没有任何东西在监听CancellationToken

If you want to implement graceful cancellation, test token inside loop and pass it to Task.Delay .如果要实现优雅取消,请在循环内测试令牌并将其传递给Task.Delay

Note, that if loadTitles is being called from UI thread, it mostly runs in the same UI thread, because there's nothing async here except Task.Delay , which preserves caller context and continues async method in UI thread.请注意,如果从 UI 线程调用loadTitles ,它主要运行在同一个 UI 线程中,因为除了Task.Delay之外,这里没有任何异步,它保留调用者上下文并在 UI 线程中继续异步方法。 To avoid this behavior you need to call ConfigureAwait(false) after Task.Delay .为了避免这种行为,您需要在Task.Delay之后调用ConfigureAwait(false)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM