【问题标题】:Waiting for event to be handled with AutoResetEvent等待使用 AutoResetEvent 处理事件
【发布时间】:2017-08-31 02:18:54
【问题描述】:

我想在网站加载之前停止执行我的代码(我使用 Windows.Forms.WebBrowser)。我读到我应该使用 AutoResetEvent,但我之前没有使用任何与线程相关的类。我写了这段代码,但它只会冻结我的程序,如何修复它?

var evt = new AutoResetEvent(false);
webBrowser.DocumentCompleted += (sender1, e1) =>
{
    if (webBrowser.ReadyState == WebBrowserReadyState.Complete)
    {
        evt.Set();
    }

};
webBrowser.Navigate("https://www.google.com/");
evt.WaitOne();      //wait to evt.Set() call
//...
//further code

【问题讨论】:

  • 为什么不将 WaitOne 之后的代码移动到 DocumentCompleted 事件处理程序中??
  • DocumentCompleted 事件只能在您的 UI 线程空闲时触发。它不是空闲的,它卡在 WaitOne() 调用上。这称为死锁。 从不阻塞 UI 线程。只需将 WaitOne 调用后的代码移动到 DocumentCompleted 事件处理程序中即可。

标签: c# .net winforms


【解决方案1】:

您可以使用 async/await 并且可以使用 TaskCompletionSource 而不是 AutoResetEvent

TaskCompletionSource<object> tcs = new TaskCompletionSource<object>();
webBrowser.DocumentCompleted += (sender1, e1) => tcs.TrySetResult(null);
webBrowser.Navigate("https://www.google.com/");
await tcs.Task;

【讨论】:

    【解决方案2】:

    我使用了调用。但是 Invoke 在另一个线程中,在本例中为 System.Timers.Timer 的 Elapsed

    MethodInvoker invoke = delegate ()
    {
         webBrowser1.Navigate(url);
    };
    this.Invoke(invoke);
    this.autoresetevent.WaitOne();
    

    和

    void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
    {
         this.autoresetevent.Set();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-29
      • 2022-01-13
      相关资源
      最近更新 更多