Open davkean opened 1 year ago
Thanks for reporting the issue and providing the telemetry that's available. I have a proposed fix in #951 based on the first suggestion. However, I'm not confident that will address the underlying issue. It seems like this would be effective if there were two threads going into the same Lazy initializer but that doesn't appear to be the case from the telemetry. I may mis-understand how the LazyThreadSafetyMode
affects other application code though?
Sorry Steve, I missed your reply to this.
It seems like this would be effective if there were two threads going into the same Lazy initializer but that doesn't appear to be the case from the telemetry.
That's the problem, we have two threads trying to get access to the Lazy initializer. When the UI thread wins and the background thread blocks, the product doesn't hang. However, when the background wins and UI thread blocks, then product hangs. This is because UI thread will not "pump" the message that the background thread needs to access the UI thread.
The fix should be good, I haven't seen an update on https://marketplace.visualstudio.com/items?itemName=SteveCadwallader.CodeMaidVS2022 with that version? This continues to rank high and has seen 173 hits past 30 days at a sampling of 10%, so the real numbers are probably close to 1730 hits.
Environment
Description
Our telemetry shows that the CodeMaid extension is hanging Visual Studio, causing folks to use TaskMgr to tear it down. Over the past 21 days, 17.3 has had (sampled) 124 hits, putting it at #90 hang overall in Visual Studio.
Steps to recreate
This is from telemetry data, there are no repro steps.
UI thread is blocked waiting on a lock:
Background thread is holding that lock (within
Lazy<T>
) and trying to switch to UI thread resulting in deadlock:Current behavior
This code is taking a lock and then attempting to switch to the UI thread while holding that lock. This switch is blocked because the UI thread is currently blocked waiting on that lock.
Expected behavior
-or-
AsyncLazy<T>
passing in ThreadHelper.JoinableTaskFactory so that the UI thread will allow the background thread to proceed and run on the UI thread if its blocked on it-or-
Lazy<T>