Как я могу определить, запущено или завершено ожидание при закрытии окна wpf

#c# #async-await #task-parallel-library

Вопрос:

Я запускаю шаблон асинхронного ожидания.
Почему в потоке выполняется переменная, равная ожиданию, по-прежнему равна нулю, пока она не завершится, я нашел.
Я думал, что это будет задача, например, есть переменная класса, определенная как

 IXPubMagickServiceCompareOutputModel _results = null;
 

Это переменная, которая равна ожиданию в асинхронном методе

  _results = await CompareImageServiceAsync(inputModel, progress,
                       PrintImagesAsyncCommand.CancellationTokenSource.Token)
                    .ConfigureAwait(false);
 

Когда эта строка может и поток ожидания выполняется, даже обрабатывается закрытие окна.
В этом случае обработчик _results переменной равен нулю, пока поток ожидания все еще запущен.
Это почему?
Я думал, что смогу выполнить _results соответствующую задачу следующим образом

 var resultsTask = (Task<IXPubMagickServiceCompareOutputModel>)_results;
 

Но я не могу, потому _result что переменная все еще равна нулю, пока выполняется задача ожидания

Комментарии:

1. Вызовите PrintImagesAsyncCommand.CancellationTokenSource.Cancel() свой OnClosing обработчик событий.

2. await не запускается, он ожидает завершения уже активной задачи без блокировки и возвращает результат, если таковой имеется. Сам код, который вы опубликовали IXPubMagickServiceCompareOutputModel _results , показывает, что _results это вообще не задача, а IXPubMagickServiceCompareOutputModel ценность.

3. Ваше сообщение выиграло бы от некоторого редактирования.

4. Задача в этом случае-это та, которая возвращается CompareImageServiceAsync() .

5.Нет никакой нити.

Ответ №1:

Я думаю, что вы хотите использовать CancellationToken .

Вот так:

 class MyWpfWindow // or MVVM ViewModel
{
    protected override void OnClosing()
    {
        CancellationTokenSource cts = this.PrintImagesAsyncCommand.CancellationTokenSource; // Create a local reference copy to avoid race-conditions.
        if( cts != null ) cts.Cancel();
    }

    private async Task DoSomethingAsync()
    {
        IXPubMagickServiceCompareOutputModel results;
        try
        {
            CancellationToken ct = this.PrintImagesAsyncCommand.CancellationTokenSource.Token;
            results = await this.CompareImageServiceAsync( inputModel, progress, ct );
            // Don't use `ConfigureAwait(false)` in WPF UI code!
        }
        catch( OperationCanceledException )
        {
            // The `OnClosing` event was invoked while `CompareImageServiceAsync` was running, so just return immediately and don't let the `OperationCanceledException` escape.
            return;
        }

        // (Do stuff with `results` here)
    }
}