C#如何使同步方法等待事件触发?

4

我有一个定制的浏览器类,可以根据浏览页面状态触发许多事件。现在,我需要使用我的浏览器对这个网页执行一些操作,但是它们必须按顺序运行,每个操作都需要前一个操作的数据。

实现这个最清晰的方式是创建一个同步方法来等待浏览器完成其工作。我像这样实现:

public incomplete class MyClass {
    // (...) lots of stuff comes here, it's a web browser :)
    public bool MySyncMethod(object data) {
        bool success = false;
        bool wait = true;
        MyEventHandler = new EventHandler((o, e) => {
            data = MyEventProvidedData; // belive me, it's threre when it fired
            success = true; // let's assume it always succeed
            wait = false; // now we can move on to the rest of our long chain
        });
        // (...) here I have some more event handlers which can end my method...
        MyAsyncMethod(data); // so it started and will fire MyEventHandler soon
        while (wait) System.Threading.Thread.Sleep(100);
        return success;
   }
}

但是这里似乎有些问题。如果我使用线程,我只需要在 while 循环中放置 myThread.Join(),它就会等待我的线程完成。是否有类似于 Thread.Join() 的东西可以与由控件触发的事件一起使用?除了 while 循环之外还有什么可以使用?这是更加清晰的实现目标的方法吗?虽然上面的代码在实际应用中可以工作,但我认为它不够优化。

而且我不在这里使用线程有一个很好的理由——所有线程和 ActiveX 控件之间的通信必须是线程安全的,而这并不容易实现。是的,我尝试过 :) 这段代码非常难以调试,所以我决定重写它。


1
你有看过 Monitor.Pulse 的示例代码吗?在 MSDN 上可以找到:http://msdn.microsoft.com/zh-cn/library/system.threading.monitor.pulse.aspx - Adriano Repetti
2个回答

10

尝试使用ManualResetEvent:

    var wait = new ManualResetEvent(false); 
    var handler = new EventHandler((o, e) => wait.Set()); 
    MyAsyncMethod(data, handler); // so it started and will fire handler soon 
    wait.WaitOne();

1
这也适用于具有多个类型的Action事件,因此可以用Action<object,int,string,int>或者你的Action看起来像什么来替换上面的EventHandler。 - NeoSkye

0

如果可以使用任务,您可以使用WaitAll方法

但是您说您不能使用线程。仍然需要启动某种线程以使asyncmethod起作用,因此必须涉及一些线程? 如果问题在于asyncmethod必须回发到原始线程以使活动x控件工作,则可以使用ASyncOperationManager(无耻的自己的博客文章链接:http://blog.subrosoftware.nl/?p=42),或者MSDN链接。这可能解决线程回调问题吗?


是的,你说得对 - 我必须使用线程,但我可以将跨线程调用限制在必要的最小范围内。我不需要直接访问ActiveX,但我需要访问基于ActiveX的WebBrowser组件。可以使用Invoke实现线程安全。因此,大部分使用浏览器的代码将在包含浏览器的窗体类中完成 - 在其线程内完成。只有启动任务和接收数据需要Invokes,所以这将非常简单。 - Harry

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接