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.
Related
I am pretty sure Applicataion.DoEvents() in Windows Forms. is a very early, very primitive, WindowsForms only form of Multitasking. It has all the telltales and mechanics:
Pausing execution of the calling Event.
Making the rest of said Event a continuation to be run later.
Allowing the other Events/Processes to run. Just with some extra issues, because the MT is implemented via the EventQueue. Possibly even a recursive call to the Queue.
But I just ran into a person that insists it has "nothing to do with Multitasking", which I cannot reconcile with my understanding of the Function or the of Multitasking.
Note: I explicitly consider Mutltithreading only an implementation for Multitasking. It is clear that DoEvents() is not a form of Multithreading, as we all know how poorly that one works in GUI Environments.
I am pretty sure it is a very early, very primitive, Windows Forms only form of Multitasking
You are pretty close to correct on all counts except for your conjecture that it is for WinForms only. "DoEvents" precedes WinForms; it was present in Visual Basic long before WinForms was invented, and "pump the message queue" obviously precedes VB also. And it was a bad idea and easily abused then too.
Making the rest of said Event a continuation to be run later.
DoEvents doesn't really make anything into a continuation the way that say, await does. Whatever event is currently "in flight" when DoEvents is called has its state on the stack, and the stack is the implementation of continuation in this case. This is another point against DoEvents -- unlike await, it eats stack, and therefore can contribute to an overflow.
I just ran into a poster that insists it has "nothing to do with Multitasking".
You should ask the author for clarification then, since that certainly sounds wrong.
Well, it's called Preemptive Multitasking, meaning "interrupting a task". You do multiple Tasks, but never two at the same time. It's not about using multiple cores of the CPU, but a way to control multiple activities inside your program.
Common Sample is, to give the program a chance to handle mouse movement by the user, while doing a lengthy operation, running something that can be considered a "batch"-job.
Normally you don't have to care about this "DoEvents", but if you know, you have a procedure running for more than 1 second, you should call it manually, you pass the control to another method thereby, you stop your own code, let other code run, and than you continue with your own code.
So it's never asynchronous, but still some kind of "multitasking".
It's more a control structure, the important thing is, you do not know what's going on inside, you call it "just for case" - somebody else might need the CPU for a millisecond.
There is no external task scheduler interrupting your code and doing a context switch, you have to "behave" by interrupting your code yourself, if you do something lengthy. It is a convention that you do only "small" things in event handlers and return the control to Windows as soon as possible,either by finishing the method, or by calling DoEvents.
Consider having an application which creates 30 app-domains, then runs them (each app-domain in its own thread) and when each of these app-domains finishes running (aka its thread exits and so on) we need to cleanup by running for each appdomain some custom cleanup-logic + a call for unloading the appdomain itself.
The cleanup logic + appdomain-unloading call for each of these app-domains might require more than one attempts to succeed (due to resources being involved, taking time to be released by the system and so on). If the cleanup operation cannot be performed in a specific attempt, it doesn't take more than 100ms for us to know about this and move on.
What is the best practice, in the world of C#, to perform such cleanup in a 'perform-cleanup-in-the-background' fashion? Possible venues off the top of my head:
Each app-domain cleanup should be performed in its very own 'new Thread()' corner. Each thread persists in a while loop with a sleep interval in case it needs to retry.
Have just a single, dedicated long-running thread with a task-queue in which we submit each and every appdomain to be cleaned-up and unloaded (again in a persistent fashion like in method #1 above).
Using a thread-pool and submitting the cleanup-tasks there
According to the following comment:
https://stackoverflow.com/a/28651533/863651
"If a method cannot be expected to exit within 100ms or so of when it starts execution, the method should be executed via some means other than the main thread pool.[ ... ] If, however, a method will take a second or longer to execute, and will spend most of its time blocked, the method should likely be run in a dedicated thread, and should almost certainly not be run in a main-threadpool thread."
I guess this discourages using method #3 above. I'm wondering if method#2 has any considerable advantages over method #1. The main thing that bugs me is that even though method#2 needs slightly more coding it uses just 1 thread no matter what, while method#2 will require N threads for N app-domains (with all the cost that this entails in terms of spawning the threads etc).
I'm open to suggestions about any method#4+ that there might be to implement such mechanism. I'm just curious to see how other programmers apply the concept of "best threading-practices" when it comes to such a problem.
Thanks in advance.
P.S.: This application is meant to be run in contemporary desktop computers (at the time of this writing).
Presuming you know what will need to be cleaned up at some point when you're managing the AppDomains, you can attach cleanup logic to the DomainUnload event like:
appDomain.DomainUnload +=
(sender, args) =>
{
//this logic needs to be specific for each AppDomain.
//you can consider using a class like BackgroundWorker to do the work.
};
For the single vs. multi-thread question, as long as you make your code thread safe, then my take is that the multi-threaded option would both reduce the lines of code (always a goal of mine) and optimize performance, especially if running cleanup as a background thread. 10s of threads is really a non-issue as far as tapping out system resources (unless cleanup operations may exhaust memory). The main drawback is that multi-threaded programs can sometimes be trickier to debug, but I bet you'll be okay in this case.
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 want to run a long running opeartion in the background.
The requirements are:
The operation should run async to the calling thread.
The calling thread can wait on the operation to complete and obtain its result
Upon timeout, the operation should be aborted at once.
I would have used task, but there is no mechanism that I know of to kill the task dead cold.
Cancel token is not suitable for me, I would only kill a task if it gets stuck for unknown reason - (a bug) , this is a fail-safe mechanism.
Needles to say if the task is stuck, there is no use in requesting cancel.
Same goes for BackgroundWorker.
Is there anything more elagent than using a shared object between the calling thread and a background thread?
There is nothing more elegant than using a shared object, since using a shared object is the elegant way of doing this :)
You cant provide a generic way of killing a task safely: Since the killer thread does not have any clue of what the killee is doing when trying to kill it, this would potentially leave your object model in a "corrupted" state.
Thread.Abort() has been created to do that the cleanest way possible: By throwing an exception (which allows "finally" statements to dispose used resources, or running transactions disposal on killed thread). But this method can make the code throw an exception in unexpected location. It is highly not recommended.
nb: Thread.Abort() does not work in any case (example: wont work if your thread is running native code via a P/Invoke for instance)
Thus, the elegant solution is to write clean code, which can decide when it wants to be killed (via a cancellation token).
nb2: The ultimate "Thread.Abort()" which will work in any case, and which which will keep things isolated: Create a new AppDomain, run your killable code in this AppDomain (via remoting), and call AppDomain.Unload() when you want to stop everything.
This is a quite extreme solution, though.
The only way to kill a thread 'dead cold' that I know of is Thread.Abort, however, you will see a lot of answers to this related question, Killing a Thread C#, indicating that it is generally bad practice to use it, except in rare occasions.
Another option is to avoid trying to kill the task dead cold and implement better error handling in your task such that it gracefully handles exceptions and situations where it 'gets stuck'.
Often times I when I see some multi-threaded code, I see Thread.Sleep() statements in the code.
I even had a crash where I was trying to figure out the problem, so commented out most of the multi-threaded code and slowly brought it and for the final piece when I added a for statement like:
for ( int i = 0; i < 1000000; ++i )
++i;
it didn't crash. So now I replaced it Thread.Sleep() and it seems to work. I can't repro it easily to post it here, but is using Thread.Sleep() necessary for multi-threaded applications?
What's the purpose of them? Would it lead to unexpected results if not used?
EDIT: Btw I am using the BackgroundWorker and only implementing my stuff in there, but not sure what causes this. Although I am using an API which is the hosting app where the app is not multi threaded. So for instance I think I can't call it's API functions on several threads at once. Not sure, but that was my guess.
Typically, Thread.Sleep is a sign of a bad design. That being said, its MUCH better than eating 100% of the CPU core time, which is what the for loop above is doing.
A better option is typically to use a WaitHandle, such as a ManualResetEvent, to trigger the continuation of the thread's execution when the "event" (which is the reason to delay) occurs. Alternatively, using a Timer can work as well in many cases.
The Thread.Sleep(1) allows switch to execution another thread. So if you have more threads than cores/processors and you know "now I did in this thread a lot of work and next work can be done little-bit later" you call Thread.Sleep(1) and allows another thread to do some work sooner than the native switcher will "pause" the currently executed thread.
Try this: Write a program that launches 100 threads, and put each of the thread into a for loop as you described. And then write another that launches 100 threads and uses Thread.Sleep instead.
Run them both and compare the CPU usage. You'll see the point. =)
Thread.Sleep() simply causes the executing thread to halt for the specified duration.
I've seen many developers use Thread.Sleep() because they don't probably handle the joining of dependent threads. They simply use Thread.Sleep() to force a thread to wait for some amount of time until the think their other threads would have finished and have their data available.
If you have two threads that need to wait on each other to proceed with their processing, you should really use the mechanisms built in to .NET that are meant to handle situations like that (ie. ManualResetEvent, etc.)
Thread.Sleep() is OK to use in some situations eg. watchdog threads.
However in your case, it may not seem to be the optimal solution as pointed out by others.
Without a code sample, it's hard to tell, but based on your description, I don't think it's a question of Thread.Sleep() or not. I would suspect that you may be suffering from a race condition - that's usually why you experience "random" buggy behavior or even "random" crashes in multithreaded code - as seems to be what you are experiencing.
For whatever reason, your for-loop may cause the subtle critical timings of the race condition to occur less often, but it won't solve the root cause. There are many pitfalls to be aware of when doing multithreaded programming, I can only advice you to read up on the topic if you want to be able to avoid these.
I'll recommend reading http://www.amazon.com/Concurrent-Programming-Windows-Joe-Duffy/dp/032143482X