У меня есть больше информации по этой проблеме (я работаю в той же команде, что и mikecamimo).
Проблема также возникает в приложении Windows Forms при правильной репликации. В оригинальном OP проблема не возникала в форме окна, потому что не было никакой блокировки. Когда блокировка вводится с помощью 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 Form, таком как служба Windows, приложение недоступно, поэтому DoEvents не может быть вызвано.
Проблема заключается в потоке и в том, что обработчик событий, связанный с виджетом. DoWork должен каким-то образом находиться в другом потоке. Это должно предотвратить блокировку AutoResetEvent.WaitOne на неопределенный срок. Я думаю ...:)
Любые идеи о том, как этого добиться, были бы фантастическими.