我有一个使用了包含线程的类的C# 2.0应用程序表单。
在线程函数中,不直接调用事件处理程序,而是被调用。这样做的效果是,拥有该线程的表单不需要调用InvokeRequired/BeginInvoke来更新其控件。
这显然与使用后台线程的 Microsoft API 方法相反,例如 System.Timers.Timer 和 System.Io.Ports.SerialPort。这种方法有什么本质上的问题吗?它在某些方面是危险的吗?
谢谢, PaulH
编辑:另外,如果窗体没有立即订阅事件会怎样?它会用窗体不感兴趣的事件堵塞窗体的消息队列吗?
在线程函数中,不直接调用事件处理程序,而是被调用。这样做的效果是,拥有该线程的表单不需要调用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";
}
}
这显然与使用后台线程的 Microsoft API 方法相反,例如 System.Timers.Timer 和 System.Io.Ports.SerialPort。这种方法有什么本质上的问题吗?它在某些方面是危险的吗?
谢谢, PaulH
编辑:另外,如果窗体没有立即订阅事件会怎样?它会用窗体不感兴趣的事件堵塞窗体的消息队列吗?