gpt4 book ai didi

c# - Application.DoEvents vs await Task.Delay 循环

转载 作者:行者123 更新时间:2023-11-30 13:44:44 27 4
gpt4 key购买 nike

令我非常不满的是,我需要在我的一个应用程序中使用 WebBrowser 控件。

我还需要做的一件事是等待元素变得可见/类更改/等,这发生在 DocumentCompleted 事件被触发之后,使事件接近无用我的情况。

所以目前我有类似...

while (webBrowser.Document?.GetElementById("id")?.GetAttribute("classname") != "class")
{
Application.DoEvents();
Thread.Sleep(1);
}

现在我在多个地方读到 DoEvents() 是邪恶的并且会导致很多问题,所以我考虑用 Task.Delay() 替换它因此:

while (webBrowser.Document?.GetElementById("id")?.GetAttribute("classname") != "class")
{
await Task.Delay(10);
}

所以我的问题是,除了 Thread.Sleep() 会阻塞事件 1ms 而 Task.Delay() 有一个更大的明显事实之外上面示例中设置的延迟,这两种方法之间的实际区别是什么,哪个更好,为什么?

PS:请坚持这个问题,虽然我不一定介意其他关于如何通过使用其他东西(js 注入(inject))修复 WebBrowser 控件问题本身的想法想到),这里不是回答这个问题的地方,这个问题是关于这两段代码有何不同以及哪一段会被认为更好。

最佳答案

what are the actual differences between doing the two approaches, which is better and why?

不同之处在于等待时消息的处理方式。

DoEvents 将安装一个嵌套的消息循环;这意味着您的堆栈将(至少)有两个消息处理循环。这causes reentrancy issues ,IMO 是避免 DoEvents 的最大原因。关于嵌套消息循环应该处理哪些类型的事件,存在无穷无尽的问题,因为该决定的双方都存在死锁,并且没有适合所有应用程序的解决方案。有关消息泵送的深入讨论,请参阅经典 Apartments and Pumping in the CLR博文。

相比之下,await返回。所以它不使用嵌套的消息循环来处理消息;它只允许原始 消息循环来处理它们。当 async 方法准备好恢复时,它会向恢复执行 async 方法的消息循环发送一条特殊消息。

因此,await 启用并发,但没有 DoEvents 中固有的所有真正困难的重入问题。 await 绝对是更好的方法。

Basically there's an ongoing argument that DoEvents() is "better" because it doesn't consume any threads from the thread pool

好吧,await 也不会消耗线程池中的任何线程。繁荣。

关于c# - Application.DoEvents vs await Task.Delay 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35188070/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com