2012-06-06 44 views
3

我有自定义浏览器类,这是能够发射大量依赖于浏览网页状态的事件的。现在,我需要使用浏览器在此网页上执行一些操作,但它们必须按顺序运行,每个操作都需要上一个操作的数据。 实现这一目标的最干净的方法是使同步方法等浏览器来完成其工作。我是这样做的:C#如何使等待事件触发的同步方法?

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; 
    } 
} 

但是这里似乎有些错误。如果我使用的线程,我只是把myThread.Join(),而不是我的while循环,它会等待我的线程来完成。它是否与Thread.Join()类似,可以与控件触发的事件一起使用?有没有什么可以用来代替while循环?这是一个更干净的方式来实现我的目标?上面的代码在真实应用程序中工作,但我认为这不是最佳的。

而且有一个很好的原因,我在这里不使用线程 - 线程和ActiveX控件必须是线程安全之间的所有通信,这是不平凡的实现。是的,我试过:)此代码是一个地狱调试,所以我决定重写它。

+0

不完整的类? –

+0

什么是“不完整”课程? –

+1

你看看Monitor.Pulse的例子代码吗?在MSDN上:http://msdn.microsoft.com/en-us/library/system.threading.monitor.pulse.aspx –

回答

7

尝试使用的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

这正是我所需要的。谢谢。 – Harry

+0

这也适用于具有多种类型的Action事件,因此上面的EventHandler可以用Action 或Action的任何形式替代。 – NeoSkye

0

如果它是可以使用的任务,你可以使用WaitAll Method

但是你说你不能使用线程。 asyncmethod仍然必须启动某种线程,因此必须涉及一些线程。 如果问题是asyncmethod必须回发到活动x控件的原始线程才能工作,那么可以使用ASyncOperationManager(无耻自己的博客帖子链接:http://blog.subrosoftware.nl/?p=42)或MSDN link这可能是否可以解决线程回调问题?

+0

是的,你是对的 - 我必须使用线程,但我可以限制跨线程调用必要的最小值。我不必直接访问ActiveX,但我需要访问基于ActiveX的WebBrowser组件。使用Invoke可以完成线程安全。因此,大多数使用浏览器的代码将在包含浏览器的表单类中完成 - 在其线程中。只有启动任务和接收数据才需要调用,因此它非常简单。 – Harry