首页 > 解决方案 > 回调在 JavaScript 与 C# 中运行时间的区别

问题描述

JavaScript 回调仅在调用堆栈为空时运行。这发生在程序执行完成或主程序调用await.

C#中任务库的回调:

  1. 假设单线程程序,行为与 JS 相同(假设await使用了而不是.Wait会导致死锁)。

  2. 但是,如果使用Task.Run,或配置 await false,回调将在响应准备好时立即运行。我假设每个线程都有自己的调用堆栈。

在 JS 和 C# 的情况下,当回调运行时,这是正确的区别吗?

标签: c#asynchronousasync-await

解决方案


在 JS 和 C# 的情况下,当回调运行时,这是正确的区别吗?

并不真地。

在 JavaScript 中,当它不做任何事情时,延续总是在主线程上运行。即使你已经完成awaitPromise,就好像你setTimeout毫不拖延地打电话一样。只要await. _ IMO,JavaScript 方法比 C# 更干净、更容易理解。但是,.NET 团队对 C# 采用了不同的方法,我认为是出于性能原因。

在 C# 中,首先要注意的是await可能会继续同步执行。如果 awaitable 已经完成,那么就不会发生屈服并且根本不存在延续-代码只是继续以相同的方法执行。如果可等待对象尚未完成,则将延续与当前上下文(SynchronizationContext.CurrentTaskScheduler.Current)一起附加到可等待对象。

当等待完成时,它会执行所有的延续。如果可能,则在当前线程(完成等待的线程)上执行延续。如果这种“内联延续”是不可能的,那么延续将排队到上下文 ( SynchronizationContext/ TaskScheduler)。然后发生的事情完全取决于上下文。例如,UI 上下文将继续排队到 UI 消息处理循环,这与 JavaScript 中的几乎相同setTimeout。作为另一个示例,线程池上下文将继续排队到线程池。


推荐阅读