我有一个问题,我一直在努力寻找,我没有幸运地在这里找到正确的答案。我的问题是当我使用 BackgroundWorker()调用函数 dosomeWork()时),则该UI会完全冻结。 我已经添加了From1的控件来进行委派,以避免更新线程错误。
public void dosomeWork()
{
.
.
.
for (int i = 0; i <= listline.Count; i += range)
{
status.Text = "test if i can change label name without freezing";
isChecked(listline.GetRange(i, range));
}
}
}
代理功能
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
Delegate del = new DELEGATE(dosomeWork);
this.Invoke(del);
Delegate del2 = new TheMethod(isChecked);
this.Invoke(del2);
}
BackgroundWorker功能
private void button1_Click(object sender, EventArgs e)
{
worker.DoWork += worker_DoWork;
worker.RunWorkerAsync();
}
通常它应该正常工作。请告知。
答案 0 :(得分:0)
您要一个单独的线程来更改GUI线程中的某些内容(即使它是在GUI线程上启动的,但仍然是单独的),并且不允许跨线程操作GUI线程项由于您遇到的原因。这就是为什么它冻结。
您需要针对所有与GUI相关的变量和控件将操作调用回GUI线程。这是我在VM中使用的方法:
public static void SafeOperationToGuiThread(Action operation)
{
System.Windows.Application.Current?.Dispatcher?.Invoke(operation);
}
您将这样使用:
public void dosomeWork()
{
for (int i = 0; i <= listline.Count; i += range)
{
MyVM.SafeOperationToGuiThread( () => {
status.Text = "test if i can change label name without freezing";
isChecked(listline.GetRange(i, range));
}
}
}
}
当我更改属性而不是控件时,我也遇到了这个问题,并且发现控件和属性不能不受跨线程操作的影响。这是我的文章:
C# WPF: Linq Fails in BackgroundWorker DoWork
备用选项
请注意,如果一个人提供了一个 run workercompleted 委托,然后又不必调用回GUI,那么它也可以通过后台工作来更新gui。我在博客上提供了一个示例:
C# WPF: Threading, Control Updating, Status Bar and Cancel Operations Example All In One