它有時想在等待事件發生時阻止我的線程。阻止並等待事件
我平時做這樣的事情:
private AutoResetEvent _autoResetEvent = new AutoResetEvent(false);
private void OnEvent(object sender, EventArgs e){
_autoResetEvent.Set();
}
// ...
button.Click += OnEvent;
try{
_autoResetEvent.WaitOne();
}
finally{
button.Click -= OnEvent;
}
但是,看來這應該是我能解壓到一個公共類(甚至一些已經存在於框架)。
我希望能夠做這樣的事情:
EventWaiter ew = new EventWaiter(button.Click);
ew.WaitOne();
EventWaiter ew2 = new EventWaiter(form.Closing);
ew2.WaitOne();
但我真的不能找到一種方法來構建這樣一個類(我無法找到傳遞一個很好的有效途徑事件作爲參數)。誰能幫忙?
舉爲什麼這可能是有用的一個例子,考慮這樣的事情:
var status = ShowStatusForm();
status.ShowInsertUsbStick();
bool cancelled = WaitForUsbStickOrCancel();
if(!cancelled){
status.ShowWritingOnUsbStick();
WriteOnUsbStick();
status.AskUserToRemoveUsbStick();
WaitForUsbStickToBeRemoved();
status.ShowFinished();
}else{
status.ShowCancelled();
}
status.WaitUntilUserPressesDone();
這比用多種方法之間展開的邏輯編寫的等效代碼更加簡明易讀。但要實現WaitForUsbStickOrCancel(),WaitForUsbStickToBeRemoved和WaitUntilUserPressesDone()(假設我們在插入或移除usb棒時得到一個事件),我需要每次都重新實現「EventWaiter」。當然,你必須小心,永遠不要在GUI線程上運行它,但有時這對於簡單代碼來說是值得的折衷。
另一種選擇將是這個樣子:
var status = ShowStatusForm();
status.ShowInsertUsbStick();
usbHandler.Inserted += OnInserted;
status.Cancel += OnCancel;
//...
void OnInserted(/*..*/){
usbHandler.Inserted -= OnInserted;
status.ShowWritingOnUsbStick();
MethodInvoker mi =() => WriteOnUsbStick();
mi.BeginInvoke(WritingDone, null);
}
void WritingDone(/*..*/){
/* EndInvoke */
status.AskUserToRemoveUsbStick();
usbHandler.Removed += OnRemoved;
}
void OnRemoved(/*..*/){
usbHandler.Removed -= OnRemoved;
status.ShowFinished();
status.Done += OnDone;
}
/* etc */
我發現更難閱讀。不可否認的是,這種流動的線性是非常直線的,但事實並非如此,我喜歡第一種風格。
這與使用ShowMessage()和Form.ShowDialog()類似 - 它們也會阻塞,直到發生某些「事件」(儘管它們將在gui線程上調用時運行消息循環)。
我很好奇,到底爲什麼你會想這樣做......你能解釋一下? – 2009-01-30 00:07:10
我仍然不明白爲什麼你想要阻止線程而不是等待事件 - 這是什麼完成的? – 2009-01-30 06:54:54
你有沒有解決這個問題?我有同樣的問題。 – Carlo 2011-10-18 00:40:16