TaskCanceledException в ShutDownListener
В настоящее время мы видим много TaskCanceledException
сбрасываемое с MS.Internal.ShutDownListener.HandleShutDown
. Это началось в середине мая и могло быть связано с некоторым обновлением до.Net или Windows 10. Мы видим это в старых (~ 2 года) и новых версиях нашего программного обеспечения, и это просто началось во всех версиях. Мы настраиваем профиль.Net 4 Client с более старой версией и.Net 4.5.1 с более новыми версиями.
Полная трассировка стека:
TaskCanceledException в System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (задача задачи) в System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (задача задачи) в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (задача задачи) в System.Windows.Threading. DispatcherOperation.Wait(TimeSpan timeout) в System.Windows.Threading.Dispatcher.InvokeImpl (операция DispatcherOperation, CancellationToken cancelationToken, тайм-аут TimeSpan) в System.Windows.Threading.Dispatcher.Invoke(Action callback, приоритет DispatcherPriority, CancellationToken cancelationToken, тайм-аут TimeSpan) в MS.Internal.WeakEventTable.OnShutDown() в MS.Internal.ShutDownListener.HandleShutDown (отправитель объекта, EventArgs e)
Вопрос в том, что вызывает это?
Сейчас мы ищем подходы, чтобы найти основную причину и в конечном итоге исправить это. Конечно, мы можем просто поймать его в конце, но это не настоящее решение. Любые намеки в направлении приветствуются. Мы хотели бы обновить этот вопрос, поскольку мы получили больше информации, чтобы иметь возможность предоставлять информацию людям, которые сталкиваются с этим позже.
Ответы
Ответ 1
Я тоже это видел. Там, где вы смотрите на источник ~ 278, существует произвольный 300-минутный временной интервал: https://referencesource.microsoft.com/#WindowsBase/Base/MS/Internal/WeakEventTable.cs
try
{
Dispatcher.Invoke((Action)OnShutDown, DispatcherPriority.Send, CancellationToken.None, TimeSpan.FromMilliseconds(300));
succeeded = true;
}
catch (TimeoutException)
{
}
Он поднимается, хотя внутренние коллекции в WeakEventTable все освобождены.
Тот, кто его написал, не ожидал, что среда выполнения будет TaskCanceledException
поскольку, вероятно, она никогда не использовалась. Обходной путь, который я принимаю, - удалить все использование WeakEventManager.
Ответ 2
Кажется, есть обходной путь, по крайней мере, для.NET Framework 4.7.2
https://github.com/Microsoft/dotnet/blob/master/Documentation/compatibility/wpf-AppDomain-shutdown-handling-may-now-call-Dispatcher.Invoke-in-cleanup-of-WeakEvents.md
изменить описание
В.NET Framework 4.7.1 и более ранних версиях WPF потенциально создает xref: System.Windows.Threading.Dispatcher? DisplayProperty = nameWithType в потоке финализатора.NET во время завершения работы AppDomain. Это было исправлено в.NET Framework 4.7.2 и более поздних версиях путем очистки слабых событий с учетом потоков. Из-за этого WPF может вызвать xref: System.Windows.Threading.Dispatcher.Invoke% 2A? DisplayProperty = nameWithType для завершения процесса очистки.
В некоторых приложениях это изменение времени финализатора может вызвать исключения во время AppDomain или завершения процесса. Как правило, это наблюдается в приложениях, которые некорректно завершают работу диспетчера, работающего в рабочих потоках, до завершения процесса или AppDomain. Такие приложения должны позаботиться о правильном управлении временем жизни диспетчеров.
Рекомендуемое действие
В.NET Framework 4.7.2 и более поздних версиях разработчики могут отключить это исправление, чтобы облегчить (но не устранить) проблемы синхронизации, которые могут возникнуть из-за изменения очистки.
Чтобы отключить изменение в очистке, используйте следующий флаг AppContext.
<configuration>
<runtime>
<AppContextSwitchOverrides value="Switch.MS.Internal.DoNotInvokeInWeakEventTableShutdownListener=true"/>
</runtime>
</configuration>