我已經得到了一些關於這個問題的更多信息(我和mikecamimo在同一個團隊工作)。
正確複製時,Windows窗體應用程序中也會出現該問題。在原來的OP中,問題沒有發生在Windows窗體中,因爲沒有阻塞。當通過使用ResetEvent引入阻塞時,會發生同樣的問題。
這是因爲事件處理函數(Widget_Completed)與調用Widget.DoWork的方法在同一個線程上。 AutoResetEvent.WaitOne();永遠阻止,因爲事件處理程序永遠不會被調用來設置事件。
在Windows窗體環境中,這可以通過使用Application.DoEvents輪詢消息隊列並允許處理事件來解決。見下文。
using System;
using System.Threading;
using System.Windows.Forms;
class Program
{
EventArgs data;
static void Main()
{
Program p = new Program();
p.RunWidget();
}
public Program()
{
_autoEvent = new AutoResetEvent(false);
}
public void RunWidget()
{
ThirdParty widget = new ThirdParty();
widget.Completed += new EventHandler(this.Widget_Completed);
data = null;
widget.DoWork();
while (data == null);
Application.DoEvents();
// do stuff with the results of DoWork that are contained in EventArgs.
}
// Assumes that some kind of args are passed by the event
public void Widget_Completed(object sender, EventArgs e)
{
data = e;
}
}
在非Windows窗體應用程序(例如Windows服務)中,應用程序不可用,因此無法調用DoEvents。
問題是線程和widget.DoWork的關聯事件處理程序之一需要在另一個線程之一。這應該防止AutoResetEvent.WaitOne無限期地被阻止。我想... :)
任何想法如何完成這將是太棒了。
我不清楚。在非Windows應用程序中異步運行時,代碼是否正常運行?或者它總是無限期地在非Windows應用程序中阻塞? – Sam 2009-01-24 06:29:03
在非Windows應用程序中,它會無限期地阻止,因爲_Complete事件永遠不會觸發,儘管嘗試了ManualResetEvents等。在Windows窗體應用程序中,它工作正常。 – mikecamimo 2009-01-24 07:25:37