我有一个Windows窗体应用程序,其中包含一个带有列表框的MAINFORM。 MAINFORM还有一个THREAD POOL,可以创建新的线程并将其激活,以执行大量不同的处理。虽然这些不同的工作线程中的每一个都正在完成其工作,但我想将此进展报告给我的MAINFORM,但是,我不能,因为它需要跨线程通信。
到目前为止,我所看到的与此主题相关的所有教程等涉及自定义(ish)线程实现,而我确实有一个相当基本的(ish)标准THREAD POOL实现。因为我不想真正修改我的任何代码(因为应用程序像没有quarms的野兽一样运行) - 我正在考虑如何进行这种跨线程通信。 ALTERNATIVELY - 如何完全实现不同的“LOGTOSCREEN”方法(显然仍然牢记跨线程通信的事情)。
我在工作中使用这个网站,我们只被锁定到IE6,因此javascript失败,这意味着我无法在工作期间点击接受任何答案,因此我的接受率很低。对此我无能为力,我很害怕,抱歉。
我没有在工作中安装我的计算机上的权利。 我有Firefox,但在Firefox上使用此站点时代理工作失败。 不,有趣的是,我家里没有互联网,我真的只是搬到了这个城市而且公寓是新建的,所以地址还没有在邮局注册,因此电话公司不能找到他们系统上的地址,直到他们派出一名测量师,聪明的裤子。
我不想改变我的演绎实施。在所有! - 接受以启用跨线程通信....为什么后台工作者会在这里提供帮助!?
当我的THREAD POOL执行新线程时,它会创建一个类的新实例并在该新线程上调用整个事件........你的代码示例不太适合....我想?
答案 0 :(得分:5)
使用.NET中的 BackgroundWorker 类并使用 ProgressChanged 和 RunWorkerCompleted 事件与UI线程进行通信
修改强>
听起来你不喜欢BackgroundWorker,或者只是不想重构。在这种情况下,您必须检查表单或其中一个控件上的 InvokeRequired 属性,如果 true ,则必须调用 Control.Invoke 强制您的UI更新逻辑在主线程上发生。
这是一个例子:
private void MyThreadFunction()
{
if (!InvokeRequired)
{
myLabel.Text = "You pushed the button!";
}
else
{
Invoke(new ThreadStart(MyThreadFunction));
}
}
您可以使用任何委托类型传递给Invoke,因为它在主线程上调用时可以传递给您的委托的可选参数。
答案 1 :(得分:2)
你可以这样做:
class MyForm : Form
{
private Label label = new Label();
private void DoWork()
{
// Do work ... Not in UI thread
// Update label... In UI thread
this.Invoke(new MethodInvoker(() => label.Text = "New Text!"));
}
}
DoWork
方法是你的工作线程中运行的方法。您可以使用InvokeRequired
属性检查是否需要调用,但假设您的代码在工作线程上运行,因此始终需要调用。
答案 2 :(得分:0)
您可以使用委托对象执行此操作。 因此,您将在MAIN表单中创建一个回调方法,并让您的CHILD表单在处理完成后使用委托调用此方法。
答案 3 :(得分:0)
尝试使用Control.BeginInvoke将更新排入UI线程上的UI。