看到这个 Blazor 小提琴:https://blazorfiddle.com/s/rckyjgd5
页面上有一个红色框。它具有“onmousemove”和“onclick”事件的处理程序。其中每一个都会导致计数增加。计数值显示在页面上。
页面上还有 4 个按钮。这些按钮会导致进行耗时的计算,但它们的执行方式略有不同。 (如果您的机器比我使用的机器快得多或慢得多,那么您可能需要调整 NumberOfIterations 属性的值,以便计算需要适当的时间 - 几秒钟是理想的。)
这个小提琴的目的是为了我自己的学习,探索异步代码在 Blazor 中的工作原理以及如何中断耗时的代码以使 UI 保持响应。对于我要问的问题来说,小提琴有点过分了。
这里有一种行为我觉得很奇怪。如果开始计算(使用前 3 个按钮之一)并且我将鼠标移动到红色方块上,则在计算发生时应发生的鼠标移动事件似乎被丢弃。在页面繁忙期间或之后,计数不会更新。但是,如果开始计算并单击红色方块,则计数会在计算完成后更新。如果我在计算运行时点击红色方块 5 次,那么当计算完成时,计数将跳增 5。因此这些事件不会被丢弃 - 它们被延迟,但它们最终会发生。
第三个按钮的行为与前两个按钮的行为相同,这一事实可以通过发布到这 2 个 Stack Overflow 问题(第一个、第二个)的答案来解释。
如果使用第四个按钮开始计算,并且我将鼠标指针移动到红色方块上,则鼠标移动事件的计数会偶尔更新。在某些时间间隔中,当我移动鼠标时,计数将更新,并且在某些时间间隔中,鼠标事件被“删除”。如果我用鼠标单击,那么所有事件都会发生,并且不会有太大的延迟,但是在浏览器繁忙时发生的事件会聚集在一起。
从这些观察看来:
我尝试使用的浏览器是 Microsoft Edge(64 位版本 123.0.2420.65)和 Mozilla Firefox(版本 123.0)。两者都表现出相同的行为。
小提琴可以成为很好的 MRE。
前 2 个按钮的方法完全相同,当您将
async
应用于某个方法时,它会更改该方法的实现并 enables 等待。如果你不等待任何事情,那就有点浪费了。对于调用者来说没有区别。
这两个按钮都会阻塞 UI 线程并阻止更新,因此结果行为是预期的。
接下来的 2 个按钮仅在使用 Yield()
或
Delay(1)
方面有所不同。
当您在 Blazor Server 上运行此代码时,它们的行为应该相同。在 Wasm 上,Yield() 不会导致任务切换,因为 SynchronizationContext.Current is null
为 true。