I've got a queue, which is basically the producer/consumer queue in the albahari.com
threading book, which takes an queue item off the queue, which is an action execution block off the queue and then calls a method to execute the actionlist within the queue item.
I can kill the queue easily enough by enqueing a null actionblock and block the main thread by doing a spin/wait with a thread.sleep() until the queue count goes to zero, and all the threads fall through the while !=null loop, thereby completing, but the method executing the last actionlist may still be executing the last thread.
Question is, is their anyway to detect if that method still has a thread executing it, like maybe using a Semaphore or counter with an Interlock to count the semaphore up at the beginning of the method and count it down at the end. So if it reaches zero, them I know its not threaded.
This is the implementing a destroy method on the interface, to close it down before calling dispose.
Use the Backgroundworker which has a completed event
If you start a thread like this:
System.Threading.Thread mythread = new System.Threading.Thread();
mythread.Start();
You can check:
mythread.IsAlive()
at any point to determine its status.
Use a PostSharp attribute on the method.
Related
I have a thread that loops while(true). I don't want to exit this thread and relaunch it. Instead, I want to control its iterations and get results from its work, every iteration.
So, basically, I want the controlling process to wait for the thread to return the results of some work, without exiting this thread. I am using ManualResetEventto Set() and Reset() the thread, which works, but I am not getting any returns
Probably you need to use some sorf of producer / consumer pattern using BlockingCollection, it is designed to make this easy.
I have a method that works on a queue. After consuming the first object in the queue, it goes to sleep for a predefined period (say 10 secs). Is there a way to wake that thread up if the queue is modified by any other thread on the 3rd or 4th second?
You should be using a collection specifically designed for such a purpose. One example is BlockingCollection, which allows you to take an item from the collection and, if there are no items to take, the method will block until there is an item to give to you. It is also a collection that is specifically designed to be manipulated from multiple threads, easing your burden on synchronization.
Note that BlockingCollection can be initialized so that it's backed with different types of collections. By default it will use a ConcurrentQueue, but there are other collections in the System.Collections.Concurrent namespace that you can use if you don't want queue semantics (it seems you do though). You can also implement your own collection implementing IProducerConsumerCollection<T> if you really need something unique.
Instead of Thread.Sleep:
You can use Monitor.Wait with a timeout and you can use Monitor.Pulseto wake it up if you need to from any thread.
Really good example/explanation here
In any case i'd recomend not to use Thread.Sleep() because it blocks thread completely.
It's much better to use AutoResetEvent or ManualResetEvent to synchronize two or more threads:
https://msdn.microsoft.com/en-us/library/system.threading.autoresetevent(v=vs.110).aspx
Servy has the correct answer for this using the Blocking Collection.
Just to add further: It creates a new thread pooled thread when "work" items become available on the queue and processes them asynchronously on that thread.
You can use one in a producer/consumer queue:
E.g.:
/// <summary>
/// Producer/consumer queue. Used when a task needs executing, it’s enqueued to ensure order,
/// allowing the caller to get on with other things. The number of consumers can be defined,
/// each running on a thread pool task thread.
/// Adapted from: http://www.albahari.com/threading/part5.aspx#_BlockingCollectionT
/// </summary>
public class ProducerConsumerQueue : IDisposable
{
private BlockingCollection<Action> _taskQ = new BlockingCollection<Action>();
public ProducerConsumerQueue(int workerCount)
{
// Create and start a separate Task for each consumer:
for (int i = 0; i < workerCount; i++)
{
Task.Factory.StartNew(Consume);
}
}
public void Dispose()
{
_taskQ.CompleteAdding();
}
public void EnqueueTask(Action action)
{
_taskQ.Add(action);
}
private void Consume()
{
// This sequence that we’re enumerating will block when no elements
// are available and will end when CompleteAdding is called.
// Note: This removes AND returns items from the collection.
foreach (Action action in _taskQ.GetConsumingEnumerable())
{
// Perform task.
action();
}
}
}
Thank you all for the options you suggested. I finally settled on AutoResetEvent for this requirement. After consuming the first object in the queue, instead of putting the main thread to Sleep, I spawned a new thread from the main thread where I called sleep. The main thread would just wait. Once the new thread wakes up, it will signal the main thread using Set and the main thread will resume. That is one part.
The second part - If any other thread modifies the queue, even that thread will call Set on the same EventWaitHandle, thus again making the main thread to resume.
This might not be an optimal solution but simpler than other approaches.
I would put the thread into a while iteration, then reduce the sleeptimer to something like 200 milliseconds.
But in every iteration I would check whether the queue was modified.
This way the Thread is constantly in the sleep-mode and kind of wakes up, when the queue was modified.
When you want to stop the thread you just set the while condition to false.
I stuck with choosing synchronization primitive.
This is the case:
I have pool of threads, that are in infinitive loop, and waits for some event. And another thread that should invoke this event. When event fires all wating thread should make one iteration and fall back for waiting event again.
Should I use manualResetEvent for this? I can't understand, is there any garanty, that if i wrote in control thread something like this
event.Set();
event.Reset();
All waiting threads make iteration, and all waiting threads makes only one, not two ore three, iterations.
Or should I use another primitive for my case?
Use Monitor.Wait(someObject) in the looping threads, and Monitor.PulseAll(someObject) in the event raising thread.
I think I need some help understanding the Dispatcher Queue.
When new work arrives it gets added at the beginning of the dispatcher queue and when the Dispatcher wants to process a working item it gets removed from the beginning.
In more general terms: If there is work it gets stored in a FIFO manner inside the queue and processed as long there is no work left.
The MSDN documentation here is referring to a loop and a frame:
The Dispatcher processes the work item queue in a loop. The loop is referred to as a frame.
But where is a loop in this context ? For me a loop is something that iterates over something and when it reaches the end it starts over again.
And what's the concept of a frame ? According to the MSDN documentation a frame is a punch of working items inside the queue ? If that's true how should the static method Disptatcher.PushFrame() be used ?
And the most interesting question is whether there is any way to get the current state of the queue especially how many items are in the queue.
Does it hold if a method that has been invoked before (and therefor put into the Dispatcher queue) gets executed that it is then removed from the queue immediately or does it last inside for another period of time ?
I know, So many questions :-)
There's very little documentation surrounding the Dispatcher, so you'll have to disassemble around a bit to know about the inner workings.
A dispatcher is basically something which performs work around the application's Message Pump. The one in question sits on top of the windows message loop.
As a consequence, there can only be one application Dispatcher - the global dispatcher object accessible by Application.Current.Dispatcher. Other dispatchers are possible by accessing Dispatcher.CurrentDispatcher, which according to the documentation
Gets the Dispatcher for the thread currently executing and creates a
new Dispatcher if one is not already associated with the thread.
However, calling Run on this new dispatcher will be blocking.
When you do a Dispatcher.PushFrame, it pushes an inner execution loop into the Dispatcher - that's the general idea of a frame. Anything that inherits from DispatcherObject such as DispatcherFrame will have its dispatcher set to the current one. We can verify this by looking at its constructor.
private Dispatcher _dispatcher;
protected DispatcherObject()
{
this._dispatcher = Dispatcher.CurrentDispatcher;
}
Of course, having a simple event loop isn't enough - there are times when you need to subvert the current event loop to force other work to be done. And that's why you have a DispatcherFrame. This is what actually constitutes the event loop. When you push a frame into the Dispatcher, this is what happens:
while (frame.Continue)
{
if (!this.GetMessage(ref msg, IntPtr.Zero, 0, 0))
{
break;
}
this.TranslateAndDispatchMessage(ref msg);
}
It is in the TranslateAndDispatchMessage that the prioritized queue in the Dispatcher gets evaluated, after a message is taken out.
If an operation takes a long time to run on the dispatcher, it temporarily stops the event loop, and because it doesn't respond to signalling, the application seems like it stops responding.
Here's an article which uses a frame to force the UI to respond by allowing the event loop to run shortly.
As for accessing the queue, as it is, there is no way to know the state of the queue outside of the Dispatcher. This is an internal detail, and it's reasonable that it's not exposed.
I have following problem:
I want to check (C#) if a thread has finished execution, i.e. if the thread method has returned. What I do now is call Thread.Join(1), but this gives a 1 ms delay. Is there any way to simply check if a thread has finished. Inspecting Thread.ThreadState just seems too cumbersome.
Use the Thread.IsAlive flag. This is to give the thread status.
For a thread you have the myThread.IsAlive property. It is false if the thread method returned or the thread was aborted.
If you don't want to block the current thread by waiting/checking for the other running thread completion, you can
implement callback method like this.
Action onCompleted = () =>
{
//On complete action
};
var thread = new Thread(
() =>
{
try
{
// Do your work
}
finally
{
onCompleted();
}
});
thread.Start();
If you are dealing with controls that doesn't support cross-thread operation, then you have to invoke the callback method
this.Invoke(onCompleted);
You could fire an event from your thread when it finishes and subscribe to that.
Alternatively you can call Thread.Join() without any arguments:
Blocks the calling thread until a thread terminates, while continuing to perform standard COM and SendMessage pumping.
Thread.Join(1) will:
Blocks the calling thread until a thread terminates or the specified time elapses, while continuing to perform standard COM and SendMessage pumping.
In this case the specified time is 1 millisecond.
Use Thread.Join(TimeSpan.Zero) It will not block the caller and returns a value indicating whether the thread has completed its work. By the way, that is the standard way of testing all WaitHandle classes as well.
I use IsAlive extensively, unless I want to block the current execution (of the calling thread), in which case I just call Join() without a parameter. Now, be aware that IsAlive may return false if the target thread has not actually started execution yet for any reason.
Carlos Merighe.
It depends on how you want to use it. Using a Join is one way. Another way of doing it is let the thread notify the caller of the thread by using an event. For instance when you have your graphical user interface (GUI) thread that calls a process which runs for a while and needs to update the GUI when it finishes, you can use the event to do this. This website gives you an idea about how to work with events:
http://msdn.microsoft.com/en-us/library/aa645739%28VS.71%29.aspx
Remember that it will result in cross-threading operations and in case you want to update the GUI from another thread, you will have to use the Invoke method of the control which you want to update.
Take a look at BackgroundWorker Class, with the OnRunWorkerCompleted you can do it.