如何在WinForm组件的UI线程上调用? [英] How to invoke on the UI thread of a WinForm Component?

查看:166
本文介绍了如何在WinForm组件的UI线程上调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编码一个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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆