I am using an external component which periodically shoots events from a worker thread. In my event handler I use a Dispatcher to invoke some method on the main thread. This works nicely...
private void HandleXYZ(object sender, EventArgs e)
{
...
if(OnTrigger != null)
dispatcher.Invoke(OnTrigger, new TimeSpan(0, 0, 1), e);
}
However, when the program shuts down and the external component Dispose()s, the program sometimes hangs (and can only be seen and killed in the task manager).
When I look at what is happening it looks like "the component" is waiting for the event to return on the main thread (it stays in the Dispose() method), while the worker thread waits for the dispatcher to invoke the mentioned call to the main thread (it hangs in the dispatcher.Invoke-line).
For now I solved the shutdown problem by adding a timeout to the Invoke, which seems to work but feels wrong.
Is there a cleaner way to do something like this? Can I force the main thread to take some time for jobs from other threads before shutting down?
I have tried to "disconnect" the event before shutting down, but that does not help, because the dispatcher is(could be) already waiting, when the program start to shut down...
PS: external component means here that I do not have access to the source code...
Yes, this is a common source of deadlock. It hangs because the dispatcher exited the dispatcher loop it won't respond to Invoke requests anymore. A quick cure is to use BeginInvoke instead, it doesn't wait for the invoke target to finish executing. Another quickie is to set the worker thread's IsBackground property to True so the CLR will kill it.
These are quick fixes and they may well work for you. Certainly on your dev machine, but if you have a nagging feeling that it may still go wrong then you're right, not observing a deadlock or threading race does not prove they are not present. There are two "good" ways to do it completely safely:
don't allow the main thread to exit until you are sure that the worker thread terminated and can no longer raise events. This answer shows the pattern.
terminate the program forcefully with Environment.Exit(). This is very crude but very effective, a sledgehammer you'll only reach for when you have a heavily threaded program where the UI thread is only second citizen. Odd as this may sound as a suitable approach, the new C++ language standard has elevated it to a supported way to terminate a program. You can read more about it in this answer. Do note how it allows for cleanup functions to be registered, you'll have to do something similar with, say, the AppDomain.ProcessExit event. Focus on the first bullet before you do this.
As for the event subscriptions, it is indeed a good idea to clean them up when you know that a particluar object is not needed anymore. Otherwise you would risk creating memory leaks. You might also want to have a look at the weak event pattern (MSDN).
Regarding the deadlock itself, without knowing your code, we can only guess.
I do not see the HandleXYZ() as a culprit, I would rather check your IDisposable() implemntaion. Have a look at the MSDN documentation and compare it to your implementation.
I suppose that somewhere in there in your implementation some method calls are made that depend on the timing of the GarbageCollector, which is indeterministic: Sometimes it may work out in your case, sometime it may not.
Related
So, I basically have this:
public void DoThisThing()
{
Task.Run(() =>
{
while(true)
{
//Do things
}
}
}
The start of the application basically calls the DoThisThing() method and enters it's own loop.
So, if I just close the application, what happens to this task? Does it just end? does it continue forever? Does it go on for a little bit until garbage collection gets it? Does it have a way to know the application ended?
I googled, but I couldn't get a simple answer, and I feel like there definitely is one.
The first question is, how this task is even executed. According to the Documentation:
Queues the specified work to run on the ThreadPool and returns a task or Task handle for that work.
Each programm starts with one Thread, but can start further. This one is the Main Thread, the GUI Thread and a few other names. As a general rule, if that main thread is ending, all others threads it started are canceled too. This is a OS level rule, to avoid Zombie Threads with infinite loops running all over the place.
The ThreadPool and all it's data - including sheduled and running Threads - will be collected by the "End of Application" Garbage Colleciton. If not, there is propably some OS features to make sure they end as well. But I prefer not to mention those OS fallbacks, as we really should not be using them ever. There are for cases when even the GC can no longe run properly (like Programm being killed via Task Manager).
One of the big challenges of Multitasking and -threading is keeping the main Thread alive, but without blocking it so further I/O can happen. In a GUI you have that work done for you (with the EventQueue).
All which is said below is implementation details - FOR WINDOWS - and mostly undocumented behavior. Do not rely on any of the information.
As an implementation detail, this task will most likely be scheduled to execute on a thread pool thread.
If the task has not started by the time the process exit starts, it won't matter it was queued in the first place.
If the task is currently executing, then according to some of the implementation details of process shutdown on Windows eventually only one thread will be executing which will not be the one executing this task. So, it will be forcibly terminated in that case.
If the task has already finished execution, whether through completion or by throwing an exception then there's no thread occupied by it. However, if the exception was left unobserved then the finalizer - should it get a chance to execute - will throw that. Please note that finalizers are also not guaranteed to execute under any circumstances.
This page should have been visible, but Microsoft's latest screw up in revoking access to old MSDN blogs continues.
Similarly, if you can manage to track the first link on this page then do so and read it.
P.S.: Here's the link for Raymond's blog. What you'll find from both sources is that only one thread continues the process shutdown.
The answer depends on the content of the while loop.
If the loop is running some logic that runs entirely within the scope and control of the main program, then closing the application will terminate everything.
However, if the loop is calling some external routines or operating system functions (Example: write to a file, open a network connection, run a command, start a batch job, etc), then closing the application will not terminate everything.
Based on your sample, in brief: Yes
Tasks that are created by TPL (using Task.Run or Task.Factory.StartNew) by default are background threads. So closing application will immediately terminate them.
This post could be helpfull.
I happened to lay my eyes on an intellisense tool tip regarding the parameter passed to System.Threading.Thread.Sleep(int millisecondsTimeout), saying something like "(…) Specify System.Threading.Timeout.Infinite to block the thread indefinitely". And I am intrigued.
I can understand why one might include short inactive delays within a possibly endless loop, thus yielding processing power to other executing threads when no immediate action in the sleeping thread is required, although I typically prefer implementing such delays with EventWaitHandlers so that I can avoid waiting a full sleeping delay if I signal the thread to gracefully end its execution from a different thread.
But I cannot see when I might need to suspend a thread indefinitely, and in a way that, as far as I can tell, can only be interrupted through a rather ungraceful Thread.Abort()/ThreadAbortException pair.
So what would be a working scenario where I might want to suspend a thread indefinitely?
It is a pretty long story and I have to wave my hands a bit to make it understandable. Most programmers think that Thread.Sleep() puts the thread to sleep and prevents it from executing any code. This is not accurate. Thread.Sleep(Infinite) is equivalent to Application.Run(). No kidding.
This doesn't happen very often in real life, it is mostly relevant in custom hosting scenarios. Getting code to run on a specific thread is in general an important feature to deal with code that is not thread-safe and the major reason why Application.Run() exists. But Windows exposes another way to do at a much lower level, the underlying api for this is QueueUserAPC(). The .NET analogue of this function is BeginInvoke().
This requires the thread to co-operate, just like it does when it calls Application.Run(). The thread must be in an "alertable wait state", executing a blocking function that can be interrupted. The CLR does not execute the sleep by itself, it passes the job to the CLR host. Most hosts will simply execute SleepEx(), passing TRUE for the bAlertable argument. The thread is now in a state to execute any requests posted by QueueUserAPC(). Just like it will be when it is actively executing inside the Application.Run() dispatcher loop.
The kernel feature is not otherwise exposed at all in the framework. It is the kind of code that is very hard to get right, re-entrancy bugs are pretty nasty. As most programmers that were bitten by Application.DoEvents() or a poorly placed MessageBox.Show() can attest. It is however a valid scenario in a custom hosting scenario. Where the host can get C# code to run on a specific thread, using this mechanism. So it is possible to pass Infinite because the designers did not want to intentionally disable this scenario. If this is made possible at all by the host author then they'd let you know about it. I don't know of a practical example.
More practically, you do use this feature every day. It is the way that System.Threading.Timer and System.Timers.Timer are implemented. Done by a thread inside the CLR which is started as soon as you use any timer, it uses SleepEx(INFINITE, TRUE) at its core.
You can use .Interrupt() to wake a sleeping thread (causing ThreadInterruptedException in the code that was calling .Sleep(), which can be caught and handled), so this provides a mechanism to say "sleep until someone prods you". I'm not saying it is necessarily the best mechanism for this, but: it may have uses for you.
How InvokeRequired and Invoke let us make our apps thread safe.
Let's consider such code:
private void ThreadSafeUpdate(string message)
{
if (this.textBoxSome.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(msg);
this.Invoke
(d, new object[] { message });
}
else
{
// It's on the same thread, no need for Invoke
this.textBoxSome.Text = message;
}
}
Is it possible to change state of InvokeRequired after InvokeRequired and before Invoke? If not, then why?
How does Invoking make it thread safe?
If InvokeRequired illustrate is current thread owning control, how would the thread know that it is or it is not the owner.
Let's consider that SomeMethod() is currently running on Thread1. We would like to call it from Thread2. Internally this method updates some field. Does Method.Invoke contain some kind of lock mechanism internally?
What if SomeMethod() takes very long time and we would like to run something other on the control owner thread. Does Invoking lock the owner thread or is it some kind of a background thread safe task?
ThreadSafeUpdate() //takes 5 minutes in Thread2
ThreadSafeUpdate() //after 2 minutes, we are running it in other thread2
ThreadSafeUpdate() //next run from Thread3
I think it is some kind of general pattern which can be implemented outside of winforms, what's its name?
Is it possible to change state of InvokeRequired
Yes, and it is a pretty common occurrence. Either because you started the thread too soon, before the form's Load event fired. Or because the user closed the window just as this code is running. In both cases this code fails with an exception. InvokeRequired fails when the thread races ahead of the window creation, the invoked code fails when the UI thread races ahead of the thread. The odds for an exception are low, too low to ever diagnose the bug when you test the code.
How Invoking make it thread safe?
You cannot make it safe with this code, it is a fundamental race. It must be made safe by interlocking the closing of the window with the thread execution. You must make sure that the thread stopped before allowing the window to close. The subject of this answer.
how would he know that he is or he is not owner.
This is something that can be discovered with a winapi call, GetWindowsThreadProcessId(). The Handle property is the fundamental oracle for that. Pretty decent test, but with the obvious flaw that it cannot work when the Handle is no longer valid. Using an oracle in general is unwise, you should always know when code runs on a worker thread. Such code is very fundamentally different from code that runs on the UI thread. It is slow code.
We would like to call it from Thread2
This is not in general possible. Marshaling a call from one thread to a specific other thread requires that other thread to co-operate. It must solve the producer-consumer problem. Take a look at the link, the fundamental solution to that problem is a dispatcher loop. You probably recognize it, that's how the UI thread of a program operates. Which must solve this problem, it gets notifications from arbitrary other threads and UI is never thread-safe. But worker threads in general don't try to solve this problem themselves, unless you write it explicitly, you need a thread-safe Queue and a loop that empties it.
What's if SomeMethod() takes very long time
Not sure I follow, the point of using threads is to let code that takes a long time not do anything to harm the responsiveness of the user interface.
I think it is some kind of general pattern
There is, it doesn't look like this. This kind of code tends to be written when you have an oh-shoot moment and discover that your UI is freezing. Bolting threading on top of code that was never designed to support threading is forever a bad idea. You'll overlook too many nasty little details. Very important to minimize the number of times the worker thread interacts with the UI thread, your code is doing the opposite. Fall in the pit of success with the BackgroundWorker class, its RunWorkerCompleted event gives a good synchronized way to update UI with the result of the background operation. And if you like Tasks then the TaskScheduler.FromCurrentSynchronizationContext() method helps you localize the interactions.
Usually, no. But it could happen if you're using await between the InvokeRequired check and Invoke call without capturing the execution context. Of course, if you're already using await, you're probably not going to be using Invoke and InvokeRequired.
EDIT: I just noticed that InvokeRequired will return false when the control handle hasn't been created yet. It shouldn't make much of a difference, because your call will fail anyway when the control hasn't quite been created yet, but it is something to keep in mind.
It doesn't make it thread-safe. It just adds the request to the control's queue, so that it's executed the next available time on the same thread the control was created on. This has more to do with windows architecture than with general thread-safety. The end result, however, is that the code runs on a single thread - of course, this still means you need to handle shared state synchronization manually, if any.
Well, it's complicated. But in the end, it boils down to comparing the thread ID of the thread that created the control, and the current thread ID. Internally, this calls the native method GetWindowThreadProcessId - the operating system keeps track of the controls (and more importantly, their message loops).
Invoke cannot return until the GUI thread returns to its message loop. Invoke itself only posts the command to the queue and waits for it to be processed. But the command is run on the GUI thread, not the Invoke-caller. So the SomeMethod calls in your example will be serialized, and the Invoke call itself will wait until the second call finishes.
This should already be answered. The key point is "only run GUI code on the GUI thread". That's how you get reliable and responsive GUI at all times.
You can use it anywhere you've got a loop or a wait on some queue. It probably isn't all that useful, although I have actually used it already a few times (mostly in legacy code).
However, all of this is just a simple explanation of the workings. The truth is, you shouldn't really need InvokeRequired... well, ever. It's an artifact of a different age. This is really mostly about juggling threads with little order, which isn't exactly a good practice. The uses I've seen are either lazy coding, or hotfixes for legacy code - using this in new code is silly. The argument for using InvokeRequired is usually like "it allows us to handle this business logic safely whether it runs in the GUI thread or not". Hopefully, you can see the problem with that logic :)
Also, it's not free thread-safety. It does introduce delays (especially when the GUI thread is also doing some work that isn't GUI - very likely in code that uses InvokeRequired in the first place). It does not protect you from accesses to the shared state from other threads. It can introduce deadlocks. And don't even get me started on doing anything with code that uses Application.DoEvents.
And of course, it's even less useful once you take await into consideration - writing asynchronous code is vastly easier, and it allows you to make sure the GUI code always runs in the GUI context, and the rest can run wherever you want (if it uses a thread at all).
In some of my integration tests I start multiple threads and wanted to ensure that when the integration test finishes (even if it fails) the thread will be cleaned up. Can anyone recommend an elegant way to do this?
Thanks
EDIT: Thanks for everyone's answers - just to clarify, 'cleaned up' was referring to when the testing threads stops and some of the other threads in a test haven't QTAgent (the testing process) was giving an error.
Make sure you keep the Thread object for every thread you create
Call Thread.Join() on all of them at the end of the test, after setting appropriate termination signals. If any thread doesn't terminate quickly enough, this should cause the test to fail even if the test would otherwise have passed.
It's impossible to answer this in more detail without knowing more about your application and test architecture.
If you are using .Net 4.0, and you know how many threads you are going to launch, you could use a CountdownEvent. Then in each thread, have a try/finally block that will set the event. In your cleanup code, wait on the event. You can add a timeout if you like and use that to indicate some error condition.
you can use task in C# 4 and use a cancellation token and/ or handle the end of the thread. see http://msdn.microsoft.com/en-us/library/dd460717.aspx
Using Thread.Join() will block your current thread until the thread you are calling join on exits. Before joining, you can signal the other threads to exit in a variety of fashions depending on the circumstances.
Calling Thread.Abort() will raise an abort exception in the target thread which will typically bring it to a stop unless you explicitly do something to prevent that. Although aborts aren't exactly elegant.
Setting Thread.IsBackground to true on your test threads will make sure they don't keep your process alive when your main threads exit. When the process exits, your background threads will take care of themselves automatically.
Personally, most of my test threads tend to be in the following pattern:
private static readonly ManualResetEvent m_ThreadsShouldExit = new ManualResetEvent(false);
private static void SomeThreadBody()
{
while(!m_ThreadsShouldExit.WaitOne(0))
{
DoSomething();
}
}
I have two background threads and a thread to handle minimization running on my WinForms Application. When the program closes, I use this method.
private void MyForm_Closing(object sender, FormClosingEventArgs e)
{
if(labelsUpdaterThread.IsAlive == true)
labelsUpdaterThread.Abort();
if(printNotifyThread.IsAlive == true)
printNotifyThread.Abort();
if(minimizeThread.IsAlive == true)
minimizeThread.Abort();
}
labelsUpdaterThread and printNotifyThread run all the time. MinimizeThread, as you might guess, only runs when the parent form is minimized. Here's my problem:
When the thread.abort methods are called in my above method, the "X" on the top right of my MdiParent form doesn't do anything. Clicking it has no effect.
When the thread.abort methods are NOT called in my above method, closing the MdiParent will sometimes throw exceptions because the Threads are still trying to access resources on the MdiParent that are no longer available, even though they are background threads!
I'm unsure as to why this is happening, doesn't make much sense to me. Thanks in advance for any help!
I agree with Paul Alexander's answer in that you should never call Thread.Abort, it's a horrible way to handle synchronization.
Additionally, you have a horrible separation of concerns here. The threads should not access resources in the form directly. There should be some sort of abstraction/shared-state in between, which is modified and read by both sides (the thread and the form, so make sure to make the instance thread-safe).
That said, if you couldn't make those changes then in the Close method, call the Thread.Abort methods in another thread with a try/catch statement around each. Log the error(s) somewhere at least.
In performing the calls to Thread.Abort on another thread, you don't block the UI thread, as the calls to Thread.Abort are not guaranteed to be instantaneous, and blocking the UI thread will cause the X to be greyed out while the UI thread cannot process Windows Messages (it also helps to guide you to a better separation of concerns).
However, you should move to abstract out the resources that are shared between the form and the thread, as well as provide a proper cancellation mechanism.
If you abstract out the resources to a class that shares the state, then your form doesn't have to do anything on close, the thread call stacks have a reference to the object that has the state and you can then call abort on those threads without worrying about the form and the threads sharing anything.
From there, you can then introduce a proper cooperative cancellation mechanism (cooperative cancellation, which Task supports in .NET 4.0, if that's available to you).
The Abort calls are probably throwing exceptions. Make sure that the pointers are valid and threads are still valid (not disposed) before calling abort.
And, in visual studio, open Debug\Exceptions... and set a check in the 'thrown' column for all exceptions so you see when something goes wrong.
First, Delete the calls to .Abort() and never use them again. Threads should never be terminated by calling Abort. It basically crashes your thread and doesn't give it a chance to release any resources properly or free any system handles. Instead create a ManualResetEvent and check that in your threads. When the event is set, they should terminate.
Thread1
while( ! _stopEvent.WaitOne(0) )
{
...do my thready work
}
Then in closing
private void MyForm_Closing(object sender, FormClosingEventArgs e)
{
_stopEvent.Set();
labelsUpdaterThread.Join();
...
}
If you don't care if the threads terminate properly on application exist, just set IsBackground = true and they'll be terminated automatically when the application exits.