I have another thread polling user input. This thread is the main thread and can sleep minutes at a time. If the user hits wants to quit it may be 2+ minutes before the console window shuts down which may feel not responsive.
How can i make this thread wake up from Thread.Sleep? Do i need to use another function to sleep and pass in a bool ref for it to check when the thread wake up and end?
Use Monitor.Wait instead, and call Monitor.Pulse or Monitor.PulseAll
to wake the thread up.
The solution is "Don't sleep on your UI thread". You should have a thread waiting for user input (not polling), and if you have a thread which needs to sleep (which probably isn't the case - it sounds like a hackish workaround to a different problem), then that should be separate thread that isn't handling the interface.
Have a look at the blocking queue:
http://msdn.microsoft.com/en-us/magazine/cc163427.aspx#S4
Couple of suggestions:
If your using explicit threads you can try setting ThreadType to "Background" to prevent it from blocking an exit.
Try this as how you block:
main thread:
AutoResetEvent waitingEvent = new AutoResetEvent(false);
bool doneFlag = false
Thread myUIInputThread = new Thread(someFunction);
myUIInputThread.Start(waitingEvent);
while (!doneFlag) {
doneFlag = waitingEvent.WaitOne(1000);
if (!doneFlag) {
Console.Writeline("Still waiting for the input thread...");
}
}
In some function:
public void someFunction(object state) {
Console.Write ("Enter something: ");
Console.Readline();
//... do your work ....
((AutoResetEvent)state).Set();
}
Not tested for exactness... YMMV :)
Related
I have a little c# app with multiple threads runing, but my main thread has to wait for all of threads to finish then it can do the rest.
problem now is that im using .join() for each thread, this seems wait for each thread to finish then it goes to next thread, which makes app not really multi-threading and take long time to finish.
so I wonder if there is any way I can get around this problem or just a way to check if there are no more threads is active.
thanks
If you're hanging on to the Thread object, you can use Thread.IsAlive.
Alternately, you might want to consider firing an event from your thread when it is done.
Thread.Join() doesn't mean your application isn't multithreaded - it tells the current thread to wait for the other thread to finish, which is exactly what you want.
Doing the following:
List<Thread> threads = new List<Thread>();
/** create each thread, Start() it, and add it to the list **/
foreach (Thread thread in threads)
{
thread.Join()
}
will continue to run the other threads, except the current/main thread (it will wait until the other threads are done).
Just use Thread.Join()
Ye, as said by Cuong Le, using Task Parallel Library would be much efficient.
However, you can Create a list of Threads and then check if they are alive or not.
var threadsList = new List<Thread>();
threadsList.Add(myThread); // to add
bool areDone = true;
foreach (Thread t in threadsList) {
if (t.IsAlive)
{
areDone = false;
break;
}
}
if (areDone)
{
// Everything is finished :O
}
Run multiple at same time but wanted to wait for all of them to finish, here's a way of doing the same with Parallel.ForEach:
var arrStr = new string[] {"1st", "2nd", "3rd"};
Parallel.ForEach<string>(arrStr, str =>
{
DoSomething(str); // your custom method you wanted to use
Debug.Print("Finished task for: " + str);
});
Debug.Print("All tasks finished");
That was the most simplest and efficient i guess it can go if in C# 4.0 if you want all tasks to run through same method
Try using BackgroundWorker
It raises an event in the main thread (RunWorkerCompleted) after its work is done
Here is one sample from previously answered question
https://stackoverflow.com/a/5551376/148697
I have the following code, could anyone please clarify my doubt below.
public static void Main() {
Thread thread = new Thread(Display);
thread.Start();
Thread.Sleep(5000);
// Throws exception, thread is terminated, cannot be restarted.
thread.Start()
}
public static void Display() {
}
It seems like in order to restart the thread I have to re-instantiate the thread again. Does this means I am creating a new thread? If I keep on creating 100 re-instiation will it create 100 threads and cause performance issue?
Yes, you either have to create a new thread or give the task to the thread pool each time to avoid a genuinely new thread being created. You can't restart a thread.
However, I'd suggest that if your task has failed to execute 100 times in a row, you have bigger problems than the performance overhead of starting new tasks.
You do not need to start the thread after sleep, the thread wake up automatically. It's the same thread.
first of all, you can't start the thread if it has already started. In your example, thread has finished it is work, that's why it is in terminated state.
you can check status using:
Thread.ThreadState
Are you trying to wake the thread up before the 5 seconds in complete? In which case you could try using Monitor (Wait, Pulse etc)
I am using following code to create and execute thread i need to stop it but cant see thread .Sleep
any ideas how can i stop for a while the execution there?
var t = new Thread(() =>
{
try
{
//Line 1
Pause here
//Line 2
Pause here
//Line 3
}
catch (Exception ca)
{
MessageBox.Show(ca.Message);
}
});
t.SetApartmentState(ApartmentState.STA);
t.Start();
If you mean that you want to instruct the Thread to wait at a particular checkpoint until some other Thread tells it to continue, one good option is to use AutoResetEvent.
t.SetApartmentState(ApartmentState.STA);
I'll work from the assumption that this was intentional. Couple of things you have to do to meet the STA contract. You have to pump a message loop, call Application.Run(). And you cannot pause, that blocks any marshaled call and makes deadlock very likely.
Not a problem, when you pump a message loop you're always in an idle 'pause' state. Make code run just as you'd normally do in a GUI main thread. Application.ExitThread ends the thread.
Use the static method Thread.Sleep(int) inside your delegate
http://msdn.microsoft.com/en-us/library/d00bd51t.aspx
Suspends the current thread for a specified time.
Are you looking for the System.Threading.Thread.Sleep() method?
add this line at the top of your code:
using System.Threading;
then you can see Thread.Sleep()
Is there a way to wake a sleeping thread in C#? So, have it sleep for either a long time and wake it when you want work processed?
An AutoResetEvent object (or another WaitHandle implementation) can be used to sleep until a signal from another thread is received:
// launch a calculation thread
var waitHandle = new AutoResetEvent(false);
int result;
var calculationThread = new Thread(
delegate
{
// this code will run on the calculation thread
result = FactorSomeLargeNumber();
waitHandle.Set();
});
calculationThread.Start();
// now that the other thread is launched, we can do something else.
DoOtherStuff();
// we've run out of other stuff to do, so sleep until calculation thread finishes
waitHandle.WaitOne();
If your thread is inside a call to Sleep, then there isn't (usually) a way to wake it up. (The only exception I'm aware of is Java, which allows a sleep to be ended early if some other thread calls thread.interrupt().)
The pattern that you're talking about seems to call for an event: the thread contains a loop, at the top of which it waits for an event to fire. If the event is currently unset, then the thread "sleeps" until some other thread fires the event. At that point, the sleeping thread wakes up and continues its work, until the next time through the loop when it sleeps to wait for another event.
There is actually a thread.Interrupt() method in C#.
While the accepted answer does describes a good pattern that you probably want in your case, I came to this question looking for Thread.Interrupt so I am putting it here.
The best solution would be to use Task objects with the default TaskFactory. This API (introduced in .NET 4.0) uses a pool of threads with work-stealing queues and all that fancy stuff.
If .NET 4.0 isn't available, then use the ThreadPool, which has a built-in work queue (which does some pool balancing but not on the same scope as the 4.0 thread pool).
If you really must do it yourself, then I recommend a BlockingCollection<T>, which is a blocking consumer/producer queue added in .NET 4.0.
If you really must do it yourself and can't use .NET 4.0, then you can use a ManualResetEvent or AutoResetEvent along with a lock-protected queue of work.
Expanding Wim's answer you can also specify a timeout for the WaitHandle.WaitOne() call. So you can use instead of Thread.Sleep(). CancellationToken struct provides you with one so you can signal your tasks like this:
string SleepAndWakeUp(string value,CancellationToken ct)
{
ct.WaitHandle.WaitOne(60000);
return value;
}
void Parent()
{
CancellationTokenSource cts = new CancellationTokenSource();
Task.Run(() => SleepAndWakeUp("Hello World!", cts.Token), cts.Token);
//Do some other work here
cts.Cancel(); //Wake up the asynch task
}
Would this thread help? C# has good functionality for thread Event handling. I've done most of my work in Python, but C# seems to have solid libraries for thread blocking.
Based on Ilia's suggestion:
t1 = new Thread(() =>
{
while (keepRunning) {
try {
DoWork();
Thread.Sleep(all_night_long);
}
catch (ThreadInterruptedException) { }
}
});
t1.Start();
and...
public void WakeUp()
{
t1.Interrupt();
}
public void StopRunningImmediately()
{
keepRunning = false;
WakeUp(); //immediately
}
This solution is crude, as there may be other reasons why the ThreadInterruptedException is thrown.
I am having a problem, for which I am not able to find a solution. The problem is as follows:
In the main thread (the default thread), I am starting a thread and then immediately in the main thread, I wait for the thread's exit by calling Thread.Join on the spawned thread. When I do that if the spawned thread tries to callback in the main thread's context by calling Dispatcher.Invoke, it hangs. Any ideas how I can allow the callback?
The callback has the logic to signal the thread to exit. Without executing the callback, the thread will never exit, and so the main thread is also stuck.
What's the point of starting a new thread if you just wait for it to complete ? Just do the work on the main thread...
I'm not exactly sure what you are asking but you may try BeginInvoke instead of Invoke
If you're only going to be waiting on the thread to terminate, you could simply have a polling loop, like this:
// var otherThread = ...;
volatile bool terminate = false;
while (!terminate)
{
Thread.Sleep(100);
}
otherThread.Join();
Then, leave it up to the callbacks to set the terminate flag to true once you're ready to join.
I had a similar problem which I finally solved in this way:
do{
// Force the dispatcher to run the queued operations
Dispatcher.CurrentDispatcher.Invoke(delegate { }, DispatcherPriority.ContextIdle);
}while(!otherthread.Join(1));
This produces a Join that doesn't block because of GUI-operations on the other thread.
The main trick here is the blocking Invoke with an empty delegate (no-operation), but with a priority setting that is less than all other items in the queue. That forces the dispatcher to work through the entire queue. (The default priority is DispatcherPriority.Normal = 9, so my DispatcherPriority.ContextIdle = 3 is well under.)
The Join() call uses a 1 ms time out, and re-empties the dispatcher queue as long as the join isn't successful.