我有一个后台工作人员,运行和寻找的东西,当它发现的东西,我想更新我的主WinForm。我遇到的问题是,当我尝试从我的后台工作人员更新我的WinForm时,出现错误,告诉我我无法修改在我的后台工作人员之外创建的东西(换句话说,我的表单中的所有东西)。当BackgroundWorker发生某些事情时,不同线程上的触发器代码?
有人可以提供一个简单的代码示例,说明如何让我的代码按照我希望的方式工作吗?谢谢!
我有一个后台工作人员,运行和寻找的东西,当它发现的东西,我想更新我的主WinForm。我遇到的问题是,当我尝试从我的后台工作人员更新我的WinForm时,出现错误,告诉我我无法修改在我的后台工作人员之外创建的东西(换句话说,我的表单中的所有东西)。当BackgroundWorker发生某些事情时,不同线程上的触发器代码?
有人可以提供一个简单的代码示例,说明如何让我的代码按照我希望的方式工作吗?谢谢!
如果我理解正确,您希望对窗体本身进行更改,但无法从窗体创建线程以外的线程更改窗体上的控件。为了解决这个问题我使用Form.Invoke()方法,像这样:
public void DoSomething(string myArg)
{
if(InvokeRequired)
{
Invoke(new Action<string>(DoSomething), myArg);
}
else
{
// Do something here
}
}
的InvokeRequired属性检查调用线程以确定它是否是正确的线程来进行更改表格,如果没有Invoke方法将调用移动到窗体的窗口线程上。
好吧,所以我坚持这个代码在我的主要形式, 那么我如何触发这在我的后台工作? – sooprise 2010-06-18 16:05:25
你把你想做的事情放在'做某事'的地方。然后你从工作者线程调用DoSomething,就好像它是魔术一样!那么它不是......第一次调用是必需的,所以它会运行调用。这会阻塞工作线程,并告诉主线程(GUI线程)基本上自己调用相同的函数。它确实,只有这一次,不需要调用;其他的运行。你可以在myArg上运行IFs和Splits,通过一个子类来完成各种事情。在返回时,工作者线程恢复。 – FastAl 2010-06-18 16:58:31
所以,如果你想说,改变一个文本框的文本属性,你可以在myArg中传递该文本,并替换'//在这里做某事':myTextBox.Text = myArg; 您还可以根据需要使用Action <>委托的不同变体向该方法添加其他参数。 – CodingGorilla 2010-06-18 17:23:32
我相信你正在寻找OnProgressChanged事件。更多相关信息,请参考:http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.onprogresschanged.aspx
注意在编码的情况下Gorilla的答案与Donn's合并后,BackgroundWorker事件已经编组到了正确的UI线程中,因此您无需警惕跨线程访问。 – 2010-06-18 15:39:49