I need to know whether Control.BeginInvoke and Control.Invoke calls will execute in the order they are called.
I have the following scenario:
UI thread is blocked
WCF thread calls Control.BeginInvoke
WCF thread calls Control.Invoke (or possibly BeginInvoke again)
UI thread is unblocked
??
The execution order of step 1-4 is guaranteed to be in the shown order (technically the order is not guaranteed to be that way, but the question I have is only relevant if the order is as shown).
The question I have is whether there is any chance that the Invoke/BeginInvoke call in step 3 is executed before the BeginInvoke call in step 2?
Also, please don't comment on blocking the UI thread.
In your case, step 2 will always execute before step 3. BeginInvoke on the UI thread will execute in the order it has been queued.
The UI thread is in fact a message pump, it has a single message queue with only one thread consuming it, so it's guaranteed that work items will be executed in the order they were queued.
It's with Delegate.BeginInvoke that the order of execution may be non-sequential.
BeginInvoke calls are queued on the destination thread (as they are posted in order of arrival).
Synchronous calls on the WCF Thread (step 3) may be executed before asynchronous calls (step 2) made from this thread.
Not enough information to give you a good answer. The UI thread is blocked so steps 2 and 3 must be running on a different thread. If there's no synchronization between the two, then how could we know any ordering?
Thread 1 Thread 2 Thread 3 Thread 4
Block UI Calls BeginInvoke
Unblock UI Calls Invoke or BeginInvoke BeginInvoke runs BeginInvoke runs
You've got a lot a parallelism going on, but from what you've described, there's no possible way we could tell you what possible orderings will occur, short of saying, "Anything." We can't even tell you that the calls to BeginInvoke won't happen before the UI thread is blocked or after the UI thread is unblocked.
No chance you can assume that but if there's actual some form of dependency between the two calls above have them waiting on a semaphore and only execute the dependent code when they're both completed.
If the reason why you're making the two calls at the same time is not performance then I would probably just execute the second call in the callback of the first (makes it a lot easier to debug).
Related
Control.Invoke() calls PostMessage() and then waits until the UI thread finishes processing the message. So why it does not calls SendMessage() instead (which by default waits until the UI thread finishes processing the message).
Control.Invoke() is a dangerous method, many .NET programmers have deadlocked their program with it. It should be very strongly avoided because of this. Simple everyday operations like closing a window become perilous. You'll want to wait until a worker thread cannot invoke anymore since nothing good happens when the thread keeps running but the UI is gone. So you signal the thread with, say, AutoResetEvent and wait for it to complete.
Such a wait is very likely to deadlock your program when the thread is calling Invoke() at just the wrong time. The thread cannot complete because it is stuck in the Invoke() call, the UI thread cannot service it since it is stuck in the wait. A "deadly embrace", neither thread can make progress and your program will hang. Quite hard to debug since it is not predictable and doesn't happen often enough, only goes wrong when the thread calls Invoke at exactly the same time.
Breaking that deadlock requires knowing that an Invoke() call is in progress so it can be cancelled. It is not knowable when you use SendMessage(). The lock on which it blocks is hidden in the OS. I've recently posted an answer about the problems with SendMessage, everything you read there applies here as well.
So Microsoft did not implement it that way and they use PostMessage. They add an entry to the invoke queue, call PostMessage to wake up the UI thread so it goes looking through that queue. And specific to Invoke over BeginInvoke, they block on a ManualResetEvent in the queue entry, signaled when the UI thread completed the call to the delegate target.
Now they can do something to avoid the deadlock, when a window closes it looks through the invoke queue and cancels any that had that window as the invoke target. Or in other words, the lock that's invisible when you use SendMessage and causes deadlock now becomes visible and can be released to break the deadlock.
I've noticed that AutoResetEvent completely freezes the message loop (sometimes) when in the middle of a WaitOne() call, effectively even blocking the signal message.
IE:
(UI) New thread spawned
(UI) Code calls WaitOne(); timeout: 10s
(T2) Thread opens device, calls Set()
(UI) WaitOne blocks message loop
(UI) WaitOne timeout elapsed, code execution continues
(UI) Main window receives signal and continues (but WaitOne failed)
Any ideas?
EDIT: added UI/T2's to specify threads. Also, I'm trying to turn a 3rd party library to synchronous. Opening devices involves an Open() call that in turn spawns an OpenOK or OpenFailed event, I'm trying to make a bool Open() call that returns true/false depending on which event was spawned.
... effectively even blocking the signal message.
You can't "block a signal" from being sent, you can only prevent the other thread from getting to the point of setting the event. Wait handles do not require a message pump at all.
The only thing I can think of may be that the COM object in question is tied to the UI thread. Accessing the COM object may be attempting to invoke back from T2 to the UI thread which is waiting for T2 to do something (deadlock). To see if this is indeed the problem make sure you are not creating or accessing the COM object on the UI thread.
This is the result of a race condition. The problem is that step 3 might be happening before step 2 because they're on different threads. Because you're using an AutoResetEvent, by the time WaitOne is called, the event is already reset.
Because of this problem, whenever possible, I generally try to avoid AutoResetEvents in favor of ManualResetEvents.
The order of events with a ManualResetEvent would be (I've listed event 2 as 2a and 2b to demonstrate that their order of operation is not guaranteed):
New Thread Spawned
a. Original thread calls WaitOne(); b. New thread calls Set();
Original thread wakes up.
Original thread calls Reset();
You might find this SO post on "Waiting on the mainthread while continuing to process"
Also checkout Calling Synchronous Methods Asynchronously from MSDN
I am aborting a thread (will be threads soon enough) and the problem is i need to stall until all threads have been aborted.
After doing the Thread.Abort(); I thought of using the Thread.Join() to wait until its been fully aborted. However that doesnt work. It just waits forever. How can i abort each thread and wait until its done before continuing?
Additional information: If your curious why - in this case I am closing a window, I pass a delegate func into the thread which it calls when its done (or aborted). If I dont stall then the window will close and the function will call invalid handles/objs. I can easily use the same method, stick a flag in and loop & sleep until all flags are set but that doesnt feel right.
I've learnt from many years experience with threads that there are a couple of rules that, if followed, make life a lot easier.
The one pertinent to this question is:
let threads control their own resources, including their lifetime.
I wouldn't abort a thread, I'd simply set up a communications method between the threads creator and the thread itself to signal the thread to terminate, and then let the thread itself shut down.
This method can often be as simple as a write-by-creator/read-by-thread flag which controls the threads main loop. If the thread has long running tasks while in the loop, you should also check periodically.
Then the creator thread should just join until the thread exits. Properly designed, you can set an upper limit to the time this will take.
Use a synchronisation object such as an Event. For example, each background thread has an Event associated with it. When the thread is terminating, it signals the Event. The main thread does a WaitHandle.WaitAll on the set of Events, and proceeds only when all Events are signalled.
Be warned that if there is a chance that the background threads will take a long time to terminate, blocking the main thread while waiting for them would create a bad user experience. So if this is the case, you may want to hide the window before blocking. Also, you'll want to test what the impact of this is on your callback delegate -- if the UI thread is blocked in a wait, will it be able to handle your delegate?
Might not a better design be not to call the delegate if the thread is being killed due to the window closing? Just have the main thread tell the background threads why they are terminating and have them skip the callback if the reason is "window closing." (This assumes that you are communicating with the threads, as Pax rightly recommends, rather than just calling Abort.)
I want to implement a timeout on the execution of tasks in a project that uses the CCR. Basically when I post an item to a Port or enqueue a Task to a DispatcherQueue I want to be able to abort the task or the thread that its running on if it takes longer than some configured time. How can I do this?
Can you confirm what you are asking? Are you running a long-lived task in the Dispatcher? Killing the thread would break the CCR model, so you need to be able to signal to the thread to finish its work and yield. Assuming it's a loop that is not finishing quick enough, you might choose to enqueue a timer:
var resultTimeoutPort = new Port<DateTime>();
dispatcherQueue.EnqueueTimer(TimeSpan.FromSeconds(RESULT_TIMEOUT),
resultTimeoutPort);
and ensure the blocking thread has available a reference to resultTimeoutPort. In the blocking loop, one of the exit conditions might be:
do
{
//foomungus amount of work
}while(resultTimeoutPort.Test()==null&&
someOtherCondition)
Please post more info if I'm barking up the wrong tree.
You could register the thread (Thread.CurrentThread) at the beginning of your CCR "Receive" handler (or in a method that calls your method via a delegate). Then you can do your periodic check and abort if necessary basically the same way you would have done it if you created the thread manually. The catch is that if you use your own Microsoft.Ccr.Core.Dispatcher with a fixed number of threads, I don't think there is a way to get those threads back once you abort them (based on my testing). So, if your dispatcher has 5 threads, you'll only be able to abort 5 times before posting will no longer work regardless of what tasks have been registered. However, if you construct a DispatcherQueue using the CLR thread pool, any CCR threads you abort will be replaced automatically and you won't have that problem. From what I've seen, although the CCR dispatcher is recommended, I think using the CLR thread pool is the way to go in this situation.
What does that method do exactly? I was thinking that it maybe went out into a separate thread, but handled things like control updating on the correct thread. But now I am starting to think that it maybe just runs on the UI thread. Which means that calling BeginInvoke on a control from the UI is pretty much the same as calling Invoke? Or?
It basically adds the delegate to a queue of "tasks to execute". The UI thread runs those tasks in order.
The difference between Control.Invoke and Control.BeginInvoke is basically that Control.Invoke block the worker thread until the task has executed on the UI thread, whereas BeginInvoke doesn't. I'm not sure offhand whether there's any difference between BeginInvoke and Invoke when you call it from the UI thread.
I'm not 100% sure I get that last sentence.
It contains "from the UI...", does that mean "you call BeginInvoke from the same thread the UI is living on?" or "on a control from the UI", that is, a control which is part of the UI?
Anyway, both methods ends up running the delegate in question on the same thread the UI lives on. The difference is of course that Invoke blocks, and BeginInvoke doesn't. The blocking relates to the thread that does the calling.
Control.BeginInvoke is generally used to update the UI/Control on the thread that created the UI. UI elements have a design constraint that they can only be updated from the creating thread.
Hence to update the UI from a different (worker / threadpool) thread, you have to switch to the right thread. Control.BeginInvoke does that for you - asynchronously (in that you dont block till the delegate is executed). Invoke does the same thing except that you block till the delegate has been executed.
1st google result - WinForms UI Thread Invokes: An In-Depth Review of Invoke/BeginInvoke/InvokeRequred
Note that if you use Control.BeginInvoke to invoke a delegate that returns something, you can then use Control.EndInvoke to access the returned value. If the delegate hasn't executed yet, EndInvoke will block until it has returned.