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