[英]Winforms call to async method hangs up program
我一直在解決這個問題,但現在我真的想了解出了什么問題。 我有一個相當簡單的應用程序(它是youtrack的turtoise SVN插件,但我可以用一個簡單的winforms應用程序重現這個問題)。
我有一個異步方法ResolveIssue
public async Task<bool> ResolveIssue(Issue issue, int revision, string[] pathList)
{
await Task.Delay(1000);
return true;
}
我要做的就是創建死鎖是在Button
事件處理程序中調用這個async方法,並調用Task.Wait
或Task.Result
,就像這樣
private void buttonOk_Click(object sender, System.EventArgs e)
{
var asyncResolvedIssue = api.ResolveIssue(issue, revision, pathList);
if (asyncResolvedIssue.Result) {} // <== deadlock!
}
現在我明白擁有異步方法並主動等待它是相當奇怪的,但為什么會產生死鎖?!
你的問題是因為你當你調用阻塞UI線程.Result
,你告訴延續后Task.Delay
到UI線程上運行。 因此,您正在阻止UI等待在等待UI變為空閑時被阻止的任務,這是一個典型的死鎖。
兩種解決方案 首先使按鈕單擊異步。
private async void buttonOk_Click(object sender, System.EventArgs e)
{
var asyncResolvedIssue = api.ResolveIssue(issue, revision, pathList);
if (await asyncResolvedIssue) {} // <== no deadlock!
}
事件處理程序是唯一允許您執行async void
。
另一個選項是告訴Task.Delay
它不需要通過將ConfigureAwait(bool)
設置為false來在UI線程上運行其余的功能。
public async Task<bool> ResolveIssue(Issue issue, int revision, string[] pathList)
{
await Task.Delay(1000).ConfigureAwait(false);
return true;
}
現在, Task.Delay
之后的代碼Task.Delay
在線程Task.Delay
線程而不是UI線程上運行,並且不會被UI線程當前被阻止的事實阻止。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.