Вот как это происходит:
- Есть кусок кода, назовем его «рабочим кодом», который ожидает некоторый асинхронный код. Для простоты предположим, что этот код ожидает Task.Delay:
Код: Выделить всё
try { await Task.Delay(5000, cancellationToken); // … } catch (OperationCanceledException) { // …. }
- Есть еще один фрагмент кода, назовем его «клиентский код», который решает отменить Task.Delay. Этот код вызывает cancelToken.Cancel. Вызов Cancel выполняется в потоке T2.
То, что происходит дальше, удивительно. . Я вижу, что в потоке T2 после вызова Cancel выполнение немедленно продолжается с блока внутри catch (OperationCanceledException). И это происходит, пока Cancel все еще находится в стеке вызовов. Это как если бы вызов Cancel был перехвачен кодом, который отменяет его. Вот снимок экрана Visual Studio, показывающий этот стек вызовов:

Больше контекста
Вот еще немного контекста о том, что фактический код делает:
Существует «рабочий код», который накапливает запросы. Запросы отправляются неким «клиентским кодом». Каждые несколько секунд «рабочий код» обрабатывает эти запросы. Обработанные запросы исключаются из очереди.
Однако время от времени «клиентский код» решает, что достиг точки, когда требуется немедленная обработка запросов. Чтобы сообщить об этом «рабочему коду», он вызывает метод Jolt, который предоставляет «рабочий код». Метод Jolt, вызываемый «клиентским кодом», реализует эту функцию путем отмены Task.Delay, который выполняется основным циклом кода работника. В коде работника Task.Delay отменен, и он приступает к обработке запросов, которые уже были в очереди.
Фактический код был упрощен до простейшей формы и код доступен на GitHub.
Среда
Проблему можно воспроизвести в консольных приложениях, фоновых агентах для универсальных приложений для Windows и фоновых агентах для универсальных приложений для Windows Phone 8.1.
Проблема не может быть воспроизведена в универсальных приложениях для Windows, где код работает так, как я ожидал, и вызов Cancel возвращается немедленно.
Подробнее здесь: https://stackoverflow.com/questions/314 ... er-returns