我在WinForms應用程序中有這種奇怪的行爲。我從我的主窗體的Form_Shown事件處理程序調用此任務。在新任務中創建WinForm UI控件後等待會導致死鎖?
Task.Run(() => WatchHistory(CancellationTokenSource.Token));
函數定義如下。 FinishedRequestItem對象是一個WinForms UI控件。它在等待Task.Delay時死鎖。我注意到一旦創建了FinishedRequestItem對象,就會創建一個新的同步上下文。該上下文與主窗體UI的上下文不同。
private async void WatchHistory(CancellationToken cancellationToken)
{
while (!cancellationToken.IsCancellationRequested)
{
var completedRequests = await processContext.ProcessRequests.ToListAsync(cancellationToken);
if (completedRequests.Any())
{
FinishedRequestItem entry = Program.Container.GetInstance<FinishedRequestItem>();
}
await Task.Delay(CurrentHistoryRefreshMilliseconds, cancellationToken);
}
}
但是,如果我使用Invoke方法創建UI控件,如下所示它不會死鎖。我很好奇爲什麼?由於該任務沒有在UI上下文中運行,因此可以防止Task.Delay在上面的代碼中恢復?
while (!cancellationToken.IsCancellationRequested)
{
var completedRequests = await processContext.ProcessRequests.ToListAsync(cancellationToken);
if (completedRequests.Any())
{
FinishedRequestItem entry = null;
this.Invoke((Action)delegate()
{
entry = Program.Container.GetInstance<FinishedRequestItem>();
});
}
await Task.Delay(CurrentHistoryRefreshMilliseconds, cancellationToken);
}
您應該只在UI線程上創建UI控件。你也不應該是'async void',而應該使用'async Task'。 –
我在我更新的代碼中使用異步任務,我知道它有一個更好的模式。但問題依然存在。我認爲它與Task.Delay嘗試在等待它的同一個線程中恢復有關。 – justcoding124