#c_sharp #wpf #async
Пытаюсь разобраться с PauseToken (Namespace: Microsoft.VisualStudio.Workspace). Не могу понять когда вызываю PauseTokenSource.Pause(); PauseToken уходит в паузу и одновременно завершает task и я получаю сообщение "Completed". Но при этом если после PauseTokenSource.Pause(); вызвать PauseTokenSource.Resume();, то task продолжит работать, но по окончании никаких сообщений не будет. Два вопроса почему так происходит, и как это можно поправить? public PauseToken PauseToken; private async Task DoDoneAsync() { FlagCommandDone = true; try { task = Task.Factory.StartNew(async () => { double i = 0; while (i < 3) { i++; await PauseToken.WaitWhilePausedAsync(); Thread.Sleep(5000); } } ); await task; } catch (Exception e) { isError = true; message = e.Message; } if (!isError) message = task.IsCompleted ? "Completed" : "Canceled"; MessageBox.Show(message); FlagCommandDone = false; }
Ответы
Ответ 1
Проблема в Task.Factory.StartNew. Этот метод запускает обыкновенные функции как Task, но для асинхронных он делает не то, что вы ожидаете. Используйте Task.Run вместо него. Давайте вспомним, как выполняются асинхронные функции. Ваш async-делегат с точки зрения внешнего кода не выполняется до конца, а завершается с первым внутренним await'ом, возвращая Task (который, в свою очередь, завершится с окончанием выполнения всей асинхронной функции). Следовательно, ваш task является не заданием выполнения всей асинхронной функции, а лишь заданием получения на неё Task'а! Действительно, сигнатура вашего async-делегата есть Task f(), а сигнатура функции, возвращённой из Task.Factory.StartNew — Taskf(). Task.Run обрабатывает эту ситуацию более ожидаемым образом: он получает Task , и делает внутри await, таким образом, вы дожидаетесь «внутреннего» таска, представляющего собой ваш асинхронный делегат. Литература: PFX team, Task.Run vs Task.Factory.StartNew (кажется, русский перевод тут).
Комментариев нет:
Отправить комментарий