SynchronizationContext and InvokeRequired
Asked Answered
V

2

6

I have been looking all over for an answer to this question, but can't seem to find a satisfactory answer. Maybe someone here can enlighten me.

I have a descendent of BindingList<T> that stores a reference to a SynchronizationContext object in order to raise its changed events on the UI thread.

Now, it's also possible that this BindingList<T> was created and used on the UI thread and not a background thread. How do I check this without a property like InvokeRequired available to me? What are the consequences of calling SynchronizationContext.Send on the UI thread?

Vilayet answered 28/3, 2011 at 22:20 Comment(2)
You'd better check this. SynchronizationContext.Current will be null when your binding list is created on a worker thread. Send() otherwise executes immediately on the UI thread.Incomprehensible
I pass the SynchronizationContext to the list as it's bound to the UI. And when I raise the ListChanged event, I check to see if I have a SynchronizationContext before I use it.Vilayet
G
3

The Send method on SynchronizationContext will execute synchronously and call the delegate on the thread to which the SynchronizationContext is bound. If the SynchronizationContext is bound to the UI thread and the code is currently executing on the UI thread then the delegate will just be invoked directly with no need to marshal between threads.

Grigsby answered 28/3, 2011 at 23:47 Comment(0)
I
-2

The send method will execute synchronously and on the UI thread, that's true. However, one possible consequence to worry about, is that calling Send will increase the call stack.

So, for example, the following code:

for (int i = 0; i < 10000000; i++) syncContext.Send(....);

will cause a StackOverflow exception... That's why it might be wise to avoid using the synchronization context if you're already running on the desired thread. I don't know of any full-proof way to check which thread was the list was created on, beside doing some internal bookkeeping.

Ieshaieso answered 8/1, 2014 at 15:53 Comment(2)
It certainly will not! To start with, the stack is a per-thread allocated structure. All send does is post the delegate and then wait for it to complete. It does this with a Mutex. The loop you posted will not increment the stack of either the worker thread or the UI thread by any more than 1 (Send on the worker thread, calling the delegate on the UI thread). If the SynchronizationContext is smart enough, calling from the UI thread will only push one frame to the stack.Abydos
In other words, no recursion occurs here.Orton

© 2022 - 2024 — McMap. All rights reserved.