簡體   English   中英

C#調用原因任務永遠不會完成

[英]C# Invoking causes Task never complete

這是我的代碼:

public void ReadCodes(){
        Task compute = Task.Run(() =>
        {
             //foo code
             foreach (var line in lines)
             {
                 //some other codes
                 SetText("doing something");
             }
        });
        compute.Wait();
        //some other foo
}
private void SetText(string text)
{
        if (this.lblUsedFiles.InvokeRequired)
        {
                SetTextCallback d = new SetTextCallback(SetText);
                this.Invoke(d, new object[] { text });
        }
        else
        {
                this.lblUsedFiles.Text = text;
        }
}

當我刪除SetText("doing something")調用ReadCodes()函數,否則它會掛起。 我的代碼出了什么問題? 我想在Task.Run()更新UI。

您的ReadCodes方法(可能在UI線程上執行)產生一個新任務,並阻塞等待它 - UI線程在完成之前不能執行任何其他操作。

但是,您的任務(在線程池上運行)調用Invoke在UI線程上運行操作,也阻塞直到完成。 由於兩個操作都被阻塞等待,因此兩者都無法繼續,從而導致死鎖。

要解決此問題,最簡單的解決方案通常是使用BeginInvoke替換您的Invoke ,從而允許您的任務繼續(並完成),而無需等待UI更新。 任務完成后,將釋放UI線程,並處理掛起的UI更新。

編輯 :響應更新的問題以包含循環:我建議您使用異步模式(在C#5中引入)。 這將完全消除UI線程阻塞,並允許您在處理每一行時立即執行UI更新。

public async Task ReadCodes()
{
    foreach (var line in lines)
    {
        string text = await Task.Run(() =>
        {
            //foo code
            // return text;
        });

        this.lblUsedFiles.Text = text;
    }
    //some other foo
}

編輯2 :我根據Peter Duniho的評論更新了我的代碼。 由於ReadCodes可能是在UI線程上調用的,因此您可以在等待每個任務時直接在其中更新UI(無需Invoke )。 我假設在//some other codes執行的后台處理可以集成到后續迭代的//foo code

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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