如何在WinForm组件的UI线程上调用? [英] How to invoke on the UI thread of a WinForm Component?
问题描述
我正在编码一个WinForm组件,在其中我启动一个Task来进行实际的处理并在延续中捕获异常。从那里,我想在UI元素上显示异常消息。
I'm coding a WinForm component where I start a Task to do the actual processing and trap the exception on a continuation. From there I want to show the exception message on a UI element.
Task myTask = Task.Factory.StartNew (() => SomeMethod(someArgs));
myTask.ContinueWith (antecedant => uiTextBox.Text = antecedant.Exception.Message,
TaskContinuationOptions.OnlyOnFaulted);
现在,我遇到了跨线程异常,因为该任务试图从a更新UI元素,显然是非UI线程。
Now I get a cross-thread exception because the task is trying to update a UI element from a, obviously, non UI thread.
但是,在Component类中没有定义Invoke或BeginInvoke。
However, there is no Invoke or BeginInvoke defined in the Component class.
更新
此外,请注意,由于Component不提供,Invoke / BeginInvoke / InvokeRequired在我的Component派生类中不可用。
Also, please note that Invoke/BeginInvoke/InvokeRequired are not available from my Component-derived class since Component doesn't provide them.
推荐答案
您可以在组件中添加一个属性,允许客户端设置一个表单引用,您可以使用该表单引用来调用其BeginInvoke()方法。
You could just add a property to your component, allows the client to set a form reference that you can use to call its BeginInvoke() method.
这也可以自动完成,最好不要让任何人忘记。这需要一点不可思议的设计时间魔力。我自己没有提出这个建议,而是从ErrorProvider组件中获得的。值得信赖的消息来源等等。将此粘贴到您的组件源代码中:
That can be done automatically as well, preferable so nobody can forget. It requires a bit of design time magic that's fairly impenetrable. I didn't come up with this by myself, I got it from the ErrorProvider component. Trusted source and all that. Paste this into your component source code:
using System.Windows.Forms;
using System.ComponentModel.Design;
...
[Browsable(false)]
public Form ParentForm { get; set; }
public override ISite Site {
set {
// Runs at design time, ensures designer initializes ParentForm
base.Site = value;
if (value != null) {
IDesignerHost service = value.GetService(typeof(IDesignerHost)) as IDesignerHost;
if (service != null) this.ParentForm = service.RootComponent as Form;
}
}
}
设计器自动设置ParentForm当用户将您的组件放在窗体上时,此属性。使用ParentForm.BeginInvoke()。
The designer automatically sets the ParentForm property when the user drops your component on a form. Use ParentForm.BeginInvoke().
这篇关于如何在WinForm组件的UI线程上调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!