我有一個使用包含線程的類的窗體的C#2.0應用程序。從線程調用Invoke/BeginInvoke
在線程函數中,不是直接調用事件處理函數,而是調用它。其效果是擁有窗體不需要調用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微軟的API使用的方法。這種方法有什麼內在的錯誤嗎?某種方式危險嗎?
感謝, PaulH
編輯:另外,如果表單沒有訂閱什麼事件,對嗎?它會阻塞表單的消息隊列中的表單不感興趣的事件嗎?
請看我的編輯 – Falcon 2010-12-01 18:35:19