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.
Related
I'm trying to start up a thread, storing it as a reference and then terminate it on a button click. But after starting the thread and having it execute some work, the reference has false in "IsAlive" and looking at the Thread.CurrentThread doesn't give me the same as i stored on execution.
Why can't i start a thread and later abort it from the same reference as i started it from?
Thread thread = new Thread(start);
thread.Start();
Thread thread = new Thread(start);
thread.Start();
void start (){`
await something();
No longer same thread
Could somebody explain why this is happening?
Thanks in advance!
In my start method i'm simply awaiting a list of tasks. I'm assuming these are executed by the thread i started the start method from, right?
Wrong.
When an await happens on an incomplete awaitable (typically: Task / Task<T> or ValueTask<T>), it registers a continuation and returns. If you return to the top of the call stack: your thread completes.
Separately, when the awaitable completes, the continuation will be invoked. This could be synchronously on the thread that is doing the completion, or it could be via a scheduler such as the sync-context.
The one thing it can't run on is the thread that did the await: because that thread has already finished.
I read about using BackgroundWorker class to implement thread in Windows Form application. I have a small question: If I want 5 threads being running at the same time to handle specified tasks, I must create 5 BackgroundWorker controls or just need one?
If you're talking just BackgroundWorker, then you'd have to create 5 backgrounds workers. If you simply want 5 threads, you can create those yourself. The issue then becomes how to communicate progress and completion back to the UI thread. With BackgroundWorker, you do that with WorkerReportsProgress/ReportProgress and the Completed event. Now, you could certain just uses the BackgroundWorker DoWork handler to spawn the threads you want and manage communication of data from those threads back to the UI thread via ReportProgress and Completed.
For example:
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
Thread thread1 = new Thread(ThreadOneEntry);
thread1.Start();
Thread thread2 = new Thread(ThreadTwoEntry);
thread2.Start();
Thread thread3 = new Thread(ThreadThreeEntry);
thread3.Start();
Thread thread4 = new Thread(ThreadFourEntry);
thread4.Start();
Thread thread5 = new Thread(ThreadFiveEntry);
thread5.Start();
thread1.Join();
thread2.Join();
thread3.Join();
thread4.Join();
thread5.Join();
// do something to report results from threads1-5
}
This, of course, doesn't do anything with progress--that would be very application specific and anything I come up with is likely to be entirely different than what you would do and be of no help. But, each thread could report progress back through the BackgroundWorker.ReportProgress method directly--you'd just have to give each thread the BackgroundWorker instances or a delegate to the ReportProgress method.
it's also not a terribly effective use of a thread for the background worker, it just goes into a wait state waiting for other threads, the DoWork event handler could just as easily do some of the work that one of the other thread entries would have...
I'd recommend using Task<T> instead of Thread if you are on .NET 3.5 or better and you want to perform background work that has results. Plus, spinning up your own threads does no load-balancing. Task through the TPL does its own load balancing...
A BackgroundWorker is basically a single thread, so you would need multiple instances if you needed to run more than one thread.
My thread:
public void main_news_thread(MainApplication main)
{
ThreadPool.QueueUserWorkItem(p => check_news(validrsslist, 0));
}
I call this thread every interval of time...
How can I know when the thread finishes so I can call two other methods which deal with the GUI? How can I refer to this threadpool thread?
Since you are talking about UI, you might want to look at BackgroundWorker, which offers a RunWorkerCompleted event that fires on the UI thread, and indicate success/failure/cancel etc.
http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker_events.aspx
Personally, though, I'd just run a callback method at the end of my worker code (remembering to switch back to the UI thread, via Dispatcher.Invoke in WPF or this.Invoke in winforms).
You can execute the methods in the thread itself (you have to take care of invoking yourself to access the gui thread):
ThreadPool.QueueUserWorkItem(p => {
check_news(validrsslist, 0);
//do something after the task is finished
});
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 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.