繁体   English   中英

从线程调用Invoke / BeginInvoke

[英]Calling Invoke/BeginInvoke from a thread

我有一个C#2.0应用程序,其表单使用包含线程的类。

在线程函数中,不是直接调用事件处理程序,而是调用它。 结果是拥有表单不需要调用InvokeRequired / BeginInvoke来更新其控件。

public class Foo
{
    private Control owner_;
    Thread thread_;

    public event EventHandler<EventArgs> FooEvent;

    public Foo(Control owner)
    {
        owner_ = owner;
        thread_ = new Thread(FooThread);
        thread_.Start();
    }

    private void FooThread()
    {
        Thread.Sleep(1000);
        for (;;)
        {
            // Invoke performed in the thread
            owner_.Invoke((EventHandler<EventArgs>)InternalFooEvent, 
                new object[] { this, new EventArgs() });
            Thread.Sleep(10);
        }
    }

    private void InternalFooEvent(object sender, EventArgs e)
    {
        EventHandler<EventArgs> evt = FooEvent;
        if (evt != null)
            evt(sender, e);
    }
}

public partial class Form1 : Form
{
    private Foo foo_;

    public Form1()
    {
        InitializeComponent();

        foo_ = new Foo(this);
        foo_.FooEvent += OnFooEvent;
    }

    private void OnFooEvent(object sender, EventArgs e)
    {
        // does not need to call InvokeRequired/BeginInvoke() 
        label_.Text = "hello";
    }
}

这显然与使用后台线程(如System.Timers.Timer和System.Io.Ports.SerialPort)的Microsoft API使用的方法相反。 这种方法有什么固有的错误吗? 它在某种程度上是危险的吗?

谢谢,PaulH


编辑:同样,如果表单没有立即订阅该活动该怎么办? 是否会阻止Form的消息队列中包含表单不感兴趣的事件?

这是一个线程安全调用,该方法将在表单的线程中处理。

从概念的角度来看它没有错。

不过,定时器对于此类任务更为优雅。 但是,可能是间隔为10ms的计时器会降低GUI的速度,这可能就是使用Invoke的原因。

您不需要调用InvokeRequired,因为很明显Control在另一个线程中。 此外,只有在想要异步调用方法时才需要调用BeginInvoke,这显然不是这里的情况。

关于您的编辑:不,消息队列不会被阻塞。 如果没有注册处理程序,则不会触发任何事件。 再看看你的代码;)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM