Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/273.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从线程调用Invoke/BeginInvoke_C#_.net_Multithreading_Events_Invoke - Fatal编程技术网

C# 从线程调用Invoke/BeginInvoke

C# 从线程调用Invoke/BeginInvoke,c#,.net,multithreading,events,invoke,C#,.net,Multithreading,Events,Invoke,我有一个C#2.0应用程序,它的表单使用一个包含线程的类 在线程函数中,将调用事件处理程序,而不是直接调用事件处理程序。其效果是拥有表单不需要调用invokererequired/BeginInvoke来更新其控件 public class Foo { private Control owner_; Thread thread_; public event EventHandler<EventArgs> FooEvent; public Foo(C

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

在线程函数中,将调用事件处理程序,而不是直接调用事件处理程序。其效果是拥有表单不需要调用invokererequired/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";
    }
}
公共类Foo
{
私人控制所有者;
螺纹螺纹;
公共事件事件处理程序;
公共Foo(控制所有者)
{
所有者=所有者;
螺纹=新螺纹(足螺纹);
线程启动();
}
私有void FooThread()
{
睡眠(1000);
对于(;;)
{
//在线程中执行的调用
所有者调用((EventHandler)InternalFooEvent,
新对象[]{this,new EventArgs()});
睡眠(10);
}
}
私有void InternalFooEvent(对象发送方,EventArgs e)
{
EventHandler evt=FooEvent;
如果(evt!=null)
evt(发送方,e);
}
}
公共部分类Form1:Form
{
私人富富屋;;
公共表格1()
{
初始化组件();
foo=新foo(本);
foo_.FooEvent+=OnFooEvent;
}
私有void OnFooEvent(对象发送方,EventArgs e)
{
//不需要调用invokererequired/BeginInvoke()
label.Text=“你好”;
}
}
这显然与Microsoft API使用的方法相反,Microsoft API使用后台线程,如System.Timers.Timer和System.Io.Ports.SerialPort。这种方法有什么内在的错误吗?在某种程度上是危险的吗

谢谢, 保罗



编辑:另外,如果表单没有立即订阅活动,该怎么办?它是否会用表单不感兴趣的事件阻塞表单的消息队列?

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

从概念的角度来看,它没有问题

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

您不需要调用InvokeRequired,因为很明显该控件位于另一个线程中。此外,BeginInvoke只需要在异步调用方法时调用,这里显然不是这样

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