❔ Deadlock with SynchonizationContext and locks?
I have quite a tricky problem
Our WinForms .NET Framework 4.8 program has a UI thread and a
System.Timers.Timer
. In the Elapsed event, I do some stuff that is dispatched to the UI thread via SynchronizationContext.Post()
.
https://paste.mod.gg/sbclvarnxuwv/0
PushNotification is a function that takes a NotificationPopup
(simply a Form with some extras) and pushes it to a queue, which dequeues those Forms and shows them on screen. Just like a popup. If I don't use that Post()
then the Forms have holes where the controls should be.
https://paste.mod.gg/sbclvarnxuwv/1
Now the thing is, on other pcs, this can lead to an exception where the thread the context is from does no longer exist. A coworker inserted some locks, which didn't really help and I don't see any obvious problem. What I did so far was instead of getting the context inside of this class itself, I got it on the ui thread and injected it into the constructor. I know the code samples are a bit over the place, but this thing is quite massive, so if something is unclear, then I'll provide some mode code8 Replies
doesn't the winforms timer automatically dispatch to the ui?
this one https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.timer?view=windowsdesktop-7.0
Timer Class (System.Windows.Forms)
Implements a timer that raises an event at user-defined intervals. This timer is optimized for use in Windows Forms applications and must be used in a window.
As the docs state: "Must be used in a window". The code where I'm using the timer isn't a window
IDK what SynchronizationContext.Post does, but you can just myForm.Invoke((MethodInvoker) delegate () => myForm.DoThing())
to get winforms to do things back on the UI thread
oh
well i see youre passing the sync context but maybe it isnt the one you expect?
id pass an Action<Action> that calls Form.Invoke
since thats guaranteed to run on the ui thread
So the call stack up until the point of the above code is
No threads are being created in the meantime so I'm certain that the SynchronizationContext is actually the context of the UI thread. I think I tried using invoke before not quite sure though. I'm gonna reevaluate this
Yeah, I'll try that.
SynchronizationContext.Post
should dispatch the execution of a delegate to the thread the context is coming from. Every thread can have such a context.Sounds dangerous, if they call ConfigureAwait(false) you're out of luck with that
Was this issue resolved? If so, run
/close
- otherwise I will mark this as stale and this post will be archived until there is new activity.