Отменить все запущенные задачи - PullRequest
0 голосов
/ 16 февраля 2019

Я не могу остановить созданную задачу. Следующий код не произойдет

ts?.Cancel();

, и вот как я запускаю задачу

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

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

        }

Я написал аналогичную функцию для четырех других функций, и задачи хорошо остановлены, но эта не работает.

Ответы [ 2 ]

0 голосов
/ 16 февраля 2019

Внутри вашего метода нет ничего, что слушает CancellationToken, кроме первой строки.

Если вы хотите реализовать постепенное отмену, протестируйте токен внутри цикла и передайте его в Task.Delay.

Обратите внимание, что если loadTitles вызывается из потока пользовательского интерфейса, он в основном выполняется в том же потоке пользовательского интерфейса, поскольку здесь нет ничего асинхронного, кроме Task.Delay, который сохраняет контекст вызывающего и продолжает асинхронный метод в потоке пользовательского интерфейса.,Чтобы избежать такого поведения, вам нужно позвонить ConfigureAwait(false) после Task.Delay.

0 голосов
/ 16 февраля 2019

Вы не можете остановить свои задачи, потому что в самом начале метода 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
    }
}
...