Joh*_*ntu 3 c# multithreading task doevents async-await
令我不满的是,我需要在我的一个应用程序中使用WebBrowser控件.
我还需要做的一件事是等待元素变为可见/类更改/等,这在DocumentCompleted
事件被触发后很好地发生,使得事件在我的情况下接近无用.
所以目前我有类似......
while (webBrowser.Document?.GetElementById("id")?.GetAttribute("classname") != "class")
{
Application.DoEvents();
Thread.Sleep(1);
}
Run Code Online (Sandbox Code Playgroud)
现在我已经阅读了多个DoEvents()
邪恶的地方并且可能会导致很多问题,所以我考虑用Task.Delay()
这样的方式替换它:
while (webBrowser.Document?.GetElementById("id")?.GetAttribute("classname") != "class")
{
await Task.Delay(10);
}
Run Code Online (Sandbox Code Playgroud)
所以我的问题是,除了明显的事实,Thread.Sleep()
意志阻止1ms的事件,并且Task.Delay()
在上面的例子中有一个更大的延迟设置,这两种方法之间的实际差异是什么,这更好,为什么?
PS:请坚持这个问题,虽然我不一定会想到如何WebBrowser
通过使用别的东西来解决控制问题本身的其他想法(想到js注入),这不是回答这个问题的地方,这个问题是关于这两位代码如何不同,哪些会被认为更好.
这两种方法之间的实际差异是什么,这更好,为什么?
区别在于等待时如何处理消息.
DoEvents
将安装嵌套的消息循环; 这意味着您的堆栈将具有(至少)两个消息处理循环.这导致了重入问题,IMO是避免的最大原因DoEvents
.关于嵌套消息循环应该处理哪种事件存在无穷无尽的问题,因为该决策的双方都存在死锁,并且没有适合所有应用程序的解决方案.有关消息抽取的深入讨论,请参阅CLR博客文章中的经典公寓和抽水.
相反,await
将返回.所以它不使用嵌套的消息循环来处理消息; 它只允许原始的消息循环来处理它们.当async
方法准备好恢复时,它将向消息循环发送一条特殊消息,该消息循环将继续执行该async
方法.
因此,await
实现并发,但没有固有的所有困难的重入问题DoEvents
.await
绝对是优越的方法.
基本上有一个持续的论点,DoEvents()是"更好",因为它不消耗线程池中的任何线程
好吧,await
也不消耗线程池中的任何线程.繁荣.
归档时间: |
|
查看次数: |
2340 次 |
最近记录: |