I'm writing a bit of code that will open a MessageBox on a separate thread to prevent the MessageBox from stopping the program. It is very very important that starting a new thread will not crash the program that I am running, but I don't know enough about threads to make sure this happens.
My question is, after starting the thread, how can I safely dispose of it after the MessageBox closes? I imagine closing/disposing of it is necessary so it's not just floating around after it is created and started.
Please advise, thanks!
var Thread = new Thread
(
()=>
{
MessageBox.Show("Buy pizza, Pay with snakes");
}
);
Thread.Start();
You don't need to do anything special.
Thread instances are automatically "cleaned up" (rather they become candidates for garbage collection) when there's no references to them (in your code) and their main method body has terminated. In fact, Thread doesn't implement IDisposable - so speaking of it's "disposal" is incorrect.
In your example, once the lambda method completes (ie the message box is closed), the thread will automatically terminate. You don't need to do anything extra.
Now there's a difference between reclaiming allocated memory and having objects become candidates for disposal/collection. Any objects allocated will remain on the GC heap until the next collection cleans them up ... but you shouldn't have to care about that.
A separate issue you may need to contend with is performing UI operations on a thread other than the main UI thread. While it is possible, you have to be careful not to reference any UI elements that are created on a different thread from the one you create.
The thread will close automatically after the scope of the lambda expression is left... in your case you don't need to worry about anything.
In general it's also good practice to set the thread to background, because if your application is closed you might get a message box just hanging out there by itself:
var thread = new Thread(
()=>
{
MessageBox.Show("Buy pizza, pay with snakes");
});
thread.IsBackground = true;
thread.Start();
Note: it's preferred that your variables start with a lower letter. For details on naming conventions please see the Microsoft Naming Guidelines.
A Thread will automatically clean itself up once the code contained within it completes. You don't have to manually dispose of it (and, in fact, it's not IDisposable!).
A few things first...
Threads don't "crash" the program unless an unhandled exception is thrown from within it.
You don't need to dispose of a thread. Finishing its main routine is enough.
If necessary, you can make your program wait for the end of the thread execution using the Join() method on your Thread instance.
And then a suggestion: it seems that you need a modeless MessageBox. AFAIK, the feasible way of doing this is creating a custom form and display it through Show() instead of ShowDialog().
In C#, you shouldn't have to care all that much once the thread goes out of scope. It's a simple answer, but simple is good: let the computer do what it's good at. :-)
You should be aware that if an exception is thrown by your worker thread and is not caught, then your application may abort (as Humberto mentioned in point #1). The example you provided is trivial, and I can't imagine that it would throw an exception, but you may want to consider at least wrapping the worker thread logic in a try/catch.
I would suggest not using a separate thread for this purpose. Create your own form for displaying the message and show it with the Show method. Creating a form like this isn't too difficult; I recommend making use of the Button.DialogResult, Form.AcceptButton, and Form.CancelButton properties. You have more control over the appearance of the form
In terms of reliability, an advantage of keeping your code out of a worker thread is that you can subscribe to the Application.ThreadException event in order to handle any exceptions that were not caught by your application's logic. This allows you to prevent your application from crashing due to an unhandled exception, but be aware that this will affect your entire application.
Related
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).
I am implementing a protocol library. Here a simplified description.
The main thread within the main function will always check, whether some data is available on the the networkstream (within a tcpclient). Let us say response is the received message and thread is a running thread.
thread = new Thread(new ThreadStart(function));
thread.IsBackground = true;
thread.Start();
while(true){
response = receiveMessage();
if (response != null)
{
thread.Suspend();
//I am searching for an alternative for the line above and not thread.Abort().
thread2 = new Thread(new ThreadStart(function2));
thread2.IsBackground = true;
thread2.Start();
}
}
So far so good, there are actually more messages to come within the while loop and there is also a statemachine for handling different sort of incoming messages, but this should be enough.
(There are also more than just the functions "function" and "function2").
So anyways how the functions look inside is not clear in this application, since the protocol is hidden from the programmer and meant to be a library. This means the protocol will start some programmer-defined functions as a thread depending on at what state in the protocol the program is.
So if then a special response is received (e.g. a callAnotherFunction message), I want to terminate
a thread (here named "thread") abruptly, lets say within 100 ms. But I do not know whether it executes within a loop or without and how much processing is needed until it terminates.
How to stop these threads without deprecated Suspend or Exceptionthrowing Abort function?
(Note that I cannot force the programmer of the functions to catch the ThreadAbortException.)
Or do I need a different programme architecture?
(Btw I have decided to put the loop within receiveMessage for polling the network stream into the main function, since anytime a message can appear).
Starting a thread without having a reliable way to terminate it is a bad practice. Suspend/Abort are one of those unreliable ways to terminate a thread because you may terminate a thread in a state that corrupts your entire program and you have no way to avoid it from happening.
You can see how to kill a thread safely here: Killing a .NET thread
If the "user" is giving you a method to run in a thread, then the user should also give you a method to stop the code from running. Think of it as a contract: you promise the user that you will call the stop method and they promise that the stop method will actually stop the thread. If your user violates that contract then they will be responsible for the issues that arise, which is good because you don't want to be responsible for your user's errors :).
Note that I cannot force the programmer of the functions to catch the ThreadAbortException.
Since Suspend/Abort are bad practice, the programmer doesn't need to catch the ThreadAbortException, however they should catch the ThreadInterruptedException as part of their "contract."
Remember that there are two situations you need to worry about:
The thread is executing some code.
The thread is in a blocking state.
In the case that the thread is executing some code, all you can do is notify the thread that it can exit and wait until it processes the notification. You may also skip the waiting and assume that you've leaked a resource, in which case it's the user's fault again because they didn't design their stop method to terminate their thread in a timely fashion.
In the case where the thread is in a blocking state and it's not blocking on a notification construct (i.e. semaphore, manual reset event, etc) then you should call Thread.Interrupt() to get it out of the blocking state- the user must handle the ThreadInterruptedException.
Suspend is really evil especially in a way you are trying to use it - to stop thread execution forever. It will leave all locks that thread had and also will not release resources.
Thread Abort is slightly better since it will at least try to terminate thread cleaner and locks will have chance to be released.
To properly do that you really need your thread's code to cooperate in termination. Events, semaphores or even simple bool value checked by the thread may be enough.
It may be better to re-architect your solution to have queue of messages and process them on separate thread. Special message may simply empty the queue.
You need some sort of cancellation protocol between your application and wherever function comes from. Then you can share some sort of cancellation token between function and your message loop. If message loop recognizes that function needs to be stopped you signal that by setting that token which must be tested by function on proper occasions. The simplest way would be to share a condition variable which can be atomically set from within your message loop and atomically read from function.
I'd however consider using the proper Asynchronous IO patterns combined with Tasks provided by the .NET framework out-of-the box along with proper cancellation mechanisms.
So function refers to code which you have little control over? This is pretty typical of 3rd party libraries. Most of the time they do not have builtin abilities to gracefully terminate long running operations. Since you have no idea how these functions are implemented you have very few options. In fact, your only guaranteed safe option is to spin these operations up in their own process and communicate with them via WCF. That way if you need to terminate the operation abruptly you would just kill the process. Killing another process will not corrupt the state of the current process like what would happen if you called Thread.Abort on thread within the current process.
I'm creating a new thread and within the background thread method I do work and then call another method to do work.
myThread = new Thread(new ThreadStart(doWork));
myThread.Start();
The problem is that when I leave the background worker method to go to another method and execute this :
browser.SelectList(Find.ById("selStartYear")).SelectByValue(startYear);
I get an InvalidCastException.
When my background worker method is finished do I need to do something with the thread? I see that I started the thread, but calling abort on it in the new method it calls just suspends the program.
Edit: I'm using WakiN and created new IE in the global scope:
IE browser = new IE("http://www.website.com/");
My worker method references this as does the failing method.
No, you do not need to do any cleanup on a thread that has finished executing. You should actually strive never to call Abort, as that's a destructive method and providing a more "polite" means of signaling the thread that it should exit immediately is preferred to ending it violently with Abort.
Also, if your job is not particularly long-running, then you should probably be using either the new Task class available in System.Threading.Tasks or using System.Threading.ThreadPool.QueueUserWorkItem() instead of spinning up your own thread.
That being said, you aren't providing enough information to answer your InvalidCastException issue. What is the cast it's trying? What is the relation (if any) between the body of doWork and the values being used in your failing statement?
Adam provided a complete answer on threading issue. I just another hint. Your thread (as I see in sample code) is not a background thread. Also I think all multi-thread applications needs a plan for a graceful exit (consider a system shutdown).
To find out what's the source of casting error, I suggest breaking that line of code into 3 lines, since one of the parameters is not in the right type.
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.