簡體   English   中英

Winforms調用異步方法掛起程序

[英]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.WaitTask.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM