【发布时间】:2017-07-29 14:13:30
【问题描述】:
我有一个线程,想用进度更新一个列表,但表单控件不是线程安全的。所以我学习了如何用这个article解决。
问题是来源更多,每个来源都有自己的列表来显示进度。那么如何让每个列表框都有自己的ThreadSafeSetText() 方法来清理代码呢?
delegate void SetTextCallback(string text);
private async void btnRun_Click(object sender, EventArgs e)
{
await Task.Run(() =>
{
importSource1();
});
//await Task.Run(() =>
//{
// importSource2();
//});
}
private void importSource1()
{
// db stuff in a Parallel.For
SetText("Result");
}
private void SetText(string text)
{
// InvokeRequired required compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if (this.lstImportSource1.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
}
else
{
this.lstImportSource1.Items.Insert(0, text);
}
}
【问题讨论】:
-
您用“extension-methods”标记了您的问题,因此您可能知道什么是 C# 中的扩展方法以及它们如何帮助您解决这个问题?
-
@Evk 是的,我对此有所了解,但不知道我的实力。我可以检查示例并添加方法。但不知道如何在里面分配一个委托?也不确定是否符合 ThreadSafe 的条件。
-
你不应该像这样打电话给
Invoke。在await之后更新 UI,当您在 UI 线程中时,而不是从您在另一个线程中运行的操作中。 -
@Servy 你的意思是我把
"strResult"保存在一个全局变量中,并在线程结束时设置listBox? -
@JuanCarlosOropeza 不,你应该从方法中返回它,而不是依赖全局状态。
标签: c# thread-safety extension-methods