简体   繁体   中英

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. But it wasn't and can't be because you immediately step into a foreach loop. You need to check it inside of aa loop:

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.

If you want to implement graceful cancellation, test token inside loop and pass it to 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. To avoid this behavior you need to call ConfigureAwait(false) after Task.Delay .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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