I have a query regarding these two working in conjunction with one another as I am not convinced they go hand in hand.
I have some code which uses the background worker and within DoWork() it performs some logic. This logic simply consumes the TcpClient object and sends data to an external device.
My question is within DoWork() I call AutoResetEvent.WaitOne(). Does this stop the current thread until AutoResetEvent.Set() is called? If for example, AutoResetEvent.Set() is never called will the Background Worker simply halt and not perform any operations?
Not sure whether this is bad design by nature but supporting it unfortunately :(
EDIT some pseudo code
bool done = false;
while (!done)
{
//some logic here
done = System.DateTime.Now.Hour == 10;
if (!done)
{
AutoResetEvent.WaitOne();
//Question will the while loop fire again or does it wait for the Set() to be called
//before continuing?
}
}
within DoWork() I call AutoResetEvent.WaitOne(). Does this stop the current thread until AutoResetEvent.Set() is called? If for example, AutoResetEvent.Set() is never called will the Background Worker simply halt and not perform any operations?
The answer to this is yes as cited from MSDN WaitHandle.WaitOne Method will:
Blocks the current thread until the current WaitHandle receives a signal.
EDIT: for your added code, the while loop will wait for the Set()
Related
I assume that I can just call
var dispatcherOp = Application.Current.Dispatcher.BeginInvoke(Action());
dispatcherOp.Completed += dispatcherOp_Completed;
but then I am a little concerned. If begininvoke is asynchronous, then What prevents the dispatcher from completing the action before I get the returned dispatcher operation and attach to the completed event.
i assume that this must be impossible, but if so, I would like to know why.
You are correct; this is not safe. You should simply await the operation.
The answer is: nothing.
There are three possible approaches:
1.) You can decide that it is not important to wait for the operation to be executed. If so, then you are choosing the fire and forget strategy.
2.) You can decide that you want a synchronous request, so you await, like SLaks suggested.
3.) You can keep the request to be asynchronous, but use a callback.
Unfortunately Dispatcher does not have a callback function it takes for begininvoke.
Synchronous operation is not desired in my program, but I realized after a google search or two that I can lock on it like this
lock (this)
{
var dispatcherOp = Application.Current.Dispatcher.BeginInvoke(MyAction, DispatcherPriority.Normal);
dispatcherOp.Completed += dispatcherOp_Completed;
}
void dispatcherOp_Completed(object sender, EventArgs e)
{
lock (this)
{
}
}
and then lock again on the same object in the completed function so that the dispatcher can't complete till you have finished attaching your handler.
There is never a reason to use Dispatcher.BeginInvoke in a modern application.
If your code models a background operation, then use async/await, with IProgress<T> for any progress updates.
If your code models an asynchronous sequence, then use Rx (Reactive Extensions) with ObserveOn to update objects with UI thread affinity.
I need to develop following scenario. I have System.Threating.Timer. On each timer tick, some values are retrieved from hardware device, this way:
lock (_synch)
{
//Read some values
}
Also I have many methods invoked in background thread, they also wants to read/write on COM to talk with device, for example:
bool WriteSometghing ()
{
lock(_synch)
{
//Write to device
}
}
It works fine. All of this is synchronised as should, there are no simultaneous access to device from threads. However, I need to my WriteSomething method to be called asynchronously to prevent blocking other operations in my background thread. So WriteSomething should start third thread, do all needed operations and destroy third thread. Of course, still I need to be sure, that there are no simultaneous access to hardware. So it should be synchronised with method called on timer tick. Also I need to synchronise WriteSomething calls (every call is fired on UDP packet receive), so WriteSomething can be invoked simultaneously but all operations inside should be syncrhonised between WriteSomething calls.
Method WriteSomething has to be called from background thread and also third thread should be created from my background thread, in place of current WriteSomething call. Can I simply create third thread as I described, put WriteSomething there and leave my lock as is? Will it be synchronised as should between my 3 threads (first - timer tick, second - background thread, third - background thread for WriteSomething).
Can you give me some tips, how it should be done?
You can simply create a Task to call WriteSomething.
var task = Task.Factory.CreateNew(WriteSomething);
That will spin up a new thread to execute the WriteSomething method. The lock inside the WriteSomething method will provide the necessary synchronization. If you want to harvest the return value, simply access task.Result.
Do note that accessing task.Result requires that the task complete. So if you write:
var task = Task.Factory.CreateNew(WriteSomething);
var rslt = task.Result;
The thread will block until the task is finished. Of course, you can do any arbitrary processing between when you start the task and when you harvest the result.
Edit
If you can't use Task, there are other ways to do this. For example:
bool result;
Thread t = new Thread((s) => { result = WriteSomething(); });
// at some point you'll want to harvest the result:
t.Join();
// Now you can access result
So let's say I have a method such as ThreadPool.QueueTask(Delegate d).
Some of these delegates need to return values, but as they cannot do this (being passed as delegates) they will need to take a value by reference as a parameter. Once the task is completed this value will have been altered, so the calling method needs to know this.
Essentially, the method passing the task to the threadpool should be waiting until it has completed.
What is the best way to do this? Should I just do Threadpool.QueueTask(Delegate d, EventWaitHandle e), or is there a more elegant way which would be obvious to people unfamiliar with that kind of thing?
Kind regards,
Fugu
You can use a ManualResetEvent:
public void TaskStartMethod()
{
ManualResetEvent waitHandle = new ManualResetEvent(false);
ThreadPool.QueueUserWorkItem(o=>
{
// Perform the task here
// Signal when done
waitHandle.Signal();
});
// Wait until the task is complete
waitHandle.WaitOne();
}
Essentially, the method passing the
task to the threadpool should be
waiting until it has completed.
The above code does that, but now I have a question: if your method is waiting for the task to be completed, then why do you even bother to perform the task on a separate thread? In other words, what you're describing is sequential execution of code rather than parallel, so the use of the ThradPool is pointless.
Alternately, you might might want to use a separate delegate as a callback:
public delegate void OnTaskCompleteDelegate(Result someResult);
public void TaskStartMethod()
{
OnTaskCompleteDelegate callback = new OnTaskCompleteDelegate(OnTaskComplete);
ThradPool.QueueUserWorkItem(o=>
{
// Perform the task
// Use the callback to notify that the
// task is complete. You can send a result
// or whatever you find necessary.
callback(new Result(...));
});
}
public void OnTaskComplete(Result someResult)
{
// Process the result
}
Update (1/24/2011):
You might not even need the callback delegate, you can just directly call OnTaskComplete and that should do the job too:
public void TaskStartMethod()
{
ThradPool.QueueUserWorkItem(o=>
{
// Perform the task
// Call the method when the task is complete
OnTaskComplete(new Result(...));
});
}
Depends on how you are doing it. To me it sounds a little like you have thread A putting a single task on the thread pool, then waiting for that to finish. That does not sound very helpful. If you are putting one task on the thread pool and waiting, just do it in your own thread.
But that is probably not what your doing!
I can see two possible good ways for using the thread pool. Thread A has multiple things that it wants to kick off in parallel, and then wait for them all to finish. In this case you need to store a handle to all of the tasks (or a result class), so you can wait for them all to finish. You can make use of semiphores or various synchronization tools (I don't do c# specifically) to avoid having to busy poll.
Another way is to use a callback at the end of the task. Thread A kicks off the task on the thread pool, then exists. The task has a handle back to the class that kicked it off, and calls a callback type function when it is completed to do finalisation type stuff.
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.
As part of a windows service
I'm accepting incoming socket connection using
myListener.BeginAcceptSocket(acceptAsync, null)
The acceptAsync function executes on a seperate thread (just as expected).
When the service is requested to shutdown, I "signal" the threads that accepted and are currently working on the sockets, to finish up.
After signaling each thread to end,I need to block until they are all done. I have a list of threads, that I thought I could iterate through and Join each thread until they were all done.
Howerver it seems that these threads don't end, but return to the pool, so the Join will wait for ever.
How do I block until a thread is returned to the pool?
You shouldn't use Join in this case. Rather, you should use a series of WaitHandles (specifically, an AutoResetEvent or ManualResetEvent) which your threads will signal when they are done with their work.
You would then call the static WaitAll method on the WaitHandle class, passing all of the events to wait on.
The canonical pattern for doing this is to use a CountdownEvent. The main thread will increment the event to indicate that it is participating and the worker threads will do the same once they start. After the worker threads have finished they will decrement the event. When the main thread is ready to wait for completion it should decrement the event and then wait on it. If you are not using .NET 4.0 then you can get an implemention of a countdown event from part 4 of Joe Albahari's threading ebook.
public class Example
{
private CountdownEvent m_Finisher = new CountdownEvent(0);
public void MainThread()
{
m_Finisher.AddCount();
// Your stuff goes here.
// myListener.BeginAcceptSocket(OnAcceptSocket, null);
m_Finisher.Signal();
m_Finisher.Wait();
}
private void OnAcceptSocket(object state)
{
m_Finisher.AddCount()
try
{
// Your stuff goes here.
}
finally
{
m_Finisher.Signal();
}
}
}
The best way would be to change acceptAsync so that it signals on a semaphore, your main thread can then wait on that semaphore.
You don't have a lot of acces to or control over Threapool threads.