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.
Related
I'm using threading in my windows form application.
Code
Thread sqlProcessThread = new Thread(new ThreadStart(doSqlWork));
sqlProcessThread.IsBackground = true;
sqlProcessThread.Start();
When ever this thread is called from my form at that time the form got hang.
How can i solve this problem with out using background worker.
You can use property InvokeRequired to check UI acess from different thread.
if (this.InvokeRequired)
{
this.Invoke(new MethodInvoker(this.updateUI));
return;
}
More information: MSDN documentation
If you use Invoke() from a background thread, it will wait for the UI to respond before continuing.
It's possible for the UI to respond to the Invoke() call by waiting on something which requires the background thread to do further processing. If that happens, you get deadlock.
If you do not require a return value from the UI call, you can often fix this by using BeginInvoke() instead of Invoke().
Calling BeginInvoke() will return immediately to the background thread that calls it, preventing the deadlock.
This has to be used with care.
I need to start a thread, but continue just after the thread is actually running. Now my code looks like:
splashthread.IsBackground = false;
splashthread.Start();
Thread.Sleep(100); // Wait for the thread to start
I'm not fond of these voodoo sleeps (to say the least), so I'm looking for more nifty way of doing the above.
Any ideas?
Something like this:
var splashStart = new ManualResetEvent(false);
var splashthread = new Thread(
() =>
{
splashStart.Set();
// Your thread code here...
});
splashthread.Start();
splashStart.WaitOne();
Don't forget to Dipose splashStart or if it's appropriate in your code use a using block.
Edit: Didn't confirm the original code in the IDE. Changed Wait to WaitOne() as per comment below.
Why do you care when the other thread starts? You well may be interested in knowing when the new thread has reached some particular milestone, and you could use any number of synchronization primitives to deal with that (in addition to events, if the new thread is going to be initializing something visible to the constructing thread, you could use a monitor lock with Monitor.Wait/Monitor.Pulse. Monitor locks are lightweight, but require a little care.
In particular, the thread which is going to wait for the other thread must check within a synclock whether the object has been initialized, before it does Monitor.Wait. Otherwise it's possible that the new thread might perform its Monitor.Pulse before the main thread has reached its Monitor.Wait. Adding the object-initialized check would prevent that scenario. If the new thread hasn't initialized the object before the launcher thread entered the synclock to check and wait, it won't be able to perform the Pulse until after the launcher thread gives up its lock via Monitor.Wait. If the new thread has initialized the object before the launcher thread entered the synclock, the launcher thread will see that and not wait at all.
i have main thread (MainThread) on which I create new thred (lets call it NewThread). In NewThread I call a method that want to invoke some method for MainThread.
The problem is that when I call NewThread.Join() from MainThread, Invoke method from NewThread cant be accomplished/terminate (and whole application freeze for ever...) because MainThread is waiting for NewThread to terminate...
sth like vicious circle... Any ideas how to solve it? I need to have possibility to terminate/abort NewThread from MainThread and be shure NewThread no longer exist.
I hope I was specific enough.
Main thread:
void method()
{
if(currentthread!=null)
{
currentthread.Join();
currentthread=null;
}
sth...
Backgroundworker worker = new Backgroundworker();
worker.DoWork += delegate (...)
{
currentthread=Thread.CurrentThread;
Func();
}
....
}
NewThread:
delegate void FuncDel();
void Func()
{
if(MainThread.InvokeRequired)
{
FuncDel funcD = new FuncDel();
MainThread.InvokeRequired(funcD);
return;
}
....
}
Well, the obvious answer is that your main thread should never Join() your worker thread if there's a chance the worker thread is going to try to Invoke() something on the main thread.
If you are only using Join() to wait for a shutdown on the main thread, you should first do something like a Thread.Abort(), or better yet, use a thread synchronization object like a Mutex or a shared variable, to indicate to the worker thread that it needs to abort. Once you have signaled the worker thread to abort, then allow your main thread to Join() it; your worker thread should always check to see if it has been aborted before trying to Invoke a method on the main thread.
If you're using Join() for some other reason, you should again look into the thread synchronization objects like a Mutex. These allow your threads to wait for each other to send them signals -- your worker thread could "wake up" your main thread before it needs to Invoke(), to ensure your main thread is getting CPU time to do it's work.
That's what Thread.Join does, it blocks your calling thread until the Joined thread terminates. I guess I don't know why you're using join if you simply want to Invoke on another thread. As was stated before, code would help clarify the situation.
You can poll ThreadState in order to check the state of your threads vs using a Join if your implementation won't allow for you to block your main thread.
It sounds like you almost want the cancellation pattern. Try this TPL option:
CancellationTokenSource cts = new CancellationTokenSource();
Task.Factory.StartNew(() =>
{
if(cts.Token.IsCancellationRequested)
return;
// Do Stuff
});
You can basically fire off a task for the operation you want to do, and if you need to cancel it, you can simply call
cts.Cancel();
Your example is pretty convoluted; having a thread spun off to invoke some method has nothing to do with the original thread.
Consider the following test snippet:
// act
AutoResetEvent workDoneEvent = new AutoResetEvent(false);
ThreadPool.QueueUserWorkItem(delegate
{
ProcessAndSignal(processor, workDoneEvent);
}, null);
// let worker thread have a go
workDoneEvent.WaitOne();
blockingFetcher.WaitForNextMessage = false;
// assert
Assert.That(processor.StopCause, Is.Null);
}
private static void ProcessAndSignal(MessageProcessor processor, AutoResetEvent workDoneEvent)
{
workDoneEvent.Set();
// this invocation will block until the WaitForNextMessageFlag is set
processor.ProcessMessages();
}
Ideal scenario:
ProcessAndSignalMethod is queued on the thread pool but does not start to execute.
The main thread blocks (autoResetEvent.WaitOne())
A worker thread starts to execute the "ProcessAndSignal" method
The worker threads has enough time to signal the flag and start execution of the ProcessMessages method
The main thread is spawned back into life and sets the property which will cause the ProcessAndSignal method to complete gracefully
Can the following scenario occur?
1) ProcessAndSignal() will start to execute before the main thread sets the AutoResetEvent to WaitOne() which will cause a deadlock (the processor.ProcessMessages() will go into an infinitive loop)
Yes, the scenario can occur. Yes it can deadlock if you don't declare the bool variable as volatile. Just don't use a bool, use an event like you did.
The logic looks weird, it smells like you are trying to let the main thread wait for the processing to be completed. The workDoneEvent doesn't actually signal that the work was done. Right now the main thread will check the assert before the worker is done, that can't be good. If the intention was that it signals that the worker is done then ProcessAndSignal should be the one calling Set(), at the end of the method. And the main thread should call WaitOne().
If this is at all accurate then you just should not use QUWI, just call ProcessAndSignal directly without using a thread. Far more efficient, zero odds for threading problems.
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 :)