Web Worker blocked by main thread in Chrome

ⅰ亾dé卋堺 提交于 2019-12-03 02:15:17

Your observation is correct. When the UI thread is blocked, network calls aren't dispatched.

Even worse, Chrome has the best behavior of the bunch. When a worker makes a XHR request when the UI thread is blocked:

  • Chrome: all requests are queued. The browser will not actually issue the requests until the UI thread unblocks. On the plus side, the worker thread is still free to run.
  • Firefox: new XMLHttpRequest() blocks until the UI thread unblocks.
  • IE: xhr.open() blocks until the UI thread unblocks.

While Chrome fortunately does not cause a worker thread to stop and wait (even though it won't get any data), Firefox and IE will cause a worker thread to wait on the UI thread when you try to make a XHR request.

There is no way to work around this; you're beholden to the browser to make requests on your behalf. I haven't done any testing with WebSockets, but they may deliver events even if the UI thread is blocked. At worst, the received messages would queue until the UI thread unblocks.

In case anyone stumbles across this, this behavior is confirmed as a bug (to the loose definition of "bug" as "does not behave as it ought to") in Blink, as of February 2015:

https://code.google.com/p/chromium/issues/detail?id=443374

I'm having the same issue, with a Web Worker that performs a sort of a keep-alive: it periodically pings the server, to inform that the page is still alive. I'm also using console.log in the worker, but i'm sure this is not the cause.

After some investigations, I can state that the problem can address two different situations:

  1. a long-time UI operation is blocking main thread and worker's requests are not executed. This is the case of sample illustrated by heliotrope. As of September 2018, the problem occurs only on Firefox and IE, since Chrome and Edge can correctly handle activities on worker when the main thread is blocked.

To solve this issue, I'm thinking at sending a special ping to the server before starting any long-time operation, to inform that he won't receive anything from me, until the operation is finished.

  1. a long-time asynchronous ajax call is being performed by main thread and worker's requests are queued. Some setting on the server is preventing from multiple ajax calls to run in parallel: other requests are queued until the first ajax call completes. The problem is server-specific, hence it does not depend on any browser in particular.

This problem is, in my case, due to ASP.NET session state locking: the ASP.NET pipeline will not process requests belonging to the same session concurrently but queues them, and executes them serially. Here is a detailed link: http://tech-journals.com/jonow/2011/10/22/the-downsides-of-asp-net-session-state.

Marking controller's session state as ReadOnly will solve the problem, while completely disabling session state in Web.config (<sessionState mode="Off" />) will seriously improve performance of the whole application.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!