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.
Related
In my application I have a queue which fires notifications whenever there are any changes to the queue, but sometimes it happens that when there are simultaneous operations on the queue event handler that it fires multiple times and that's okay, but what I don't want is,...
Below is the code for the event handler:
private async void NotificationQueue_Changed(object sender, EventArgs e)
{
if (!IsQueueInProcess)
await ProcessQeueue();
}
In ProcessQueue method I am setting IsQueueInProcess to true and whenever it gets completed it is set to false. Now, the problem is that whenever multiple event notifications fire simultaneously multiple ProcessQeueue methods start executing, which I don't want. I want to make sure that there will be only one execution of ProcessQeueue at any given time.
Given your statement that this event is raised whenever there are any changes to the queue, and that the queue can be used concurrently (i.e. there are multiple producers adding things to the queue), it seems likely to me that the best way to address this would be to abandon the event-based behavior altogether. Instead, using BlockingCollection<T>, with a thread dedicated to processing the queue via GetConsumingEnumerable(). That method will block the thread as long as the queue is empty, and will allow the thread to remove and process items in the queue any time any other thread adds something to it. The collection itself is thread-safe, so using that you would not require any additional thread synchronization (for the handling of the queue, that is…it's possible processing an item involves thread interactions, but there's nothing in your question that describes that aspect, so I can't say one way or the other anything about that).
That said, taking the question literally, the simplest approach would be to include a semaphore:
private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1);
private async void NotificationQueue_Changed(object sender, EventArgs e)
{
if (_semaphore.Wait(0))
{
await ProcessQueue();
_semaphore.Release();
}
}
The above attempts to acquire the semaphore's lock. With a timeout of 0 milliseconds, it will return immediately even if the semaphore could not be acquired. The return value indicates whether the semaphore was successfully acquired or not.
In this way, as long as there is no outstanding queue-processing operation, the current event handler invocation can acquire the semaphore and will call the ProcessQueue() method. When that operation completes, the continuation will release the semaphore. Until that happens, no other invocation of the event handler will be able to acquire the semaphore, and thus will not initiate processing of the queue.
I'll note that nothing here guarantees a solution to threads racing with each other that would ensure the queue is always either empty, or always has some processing operation acting on it. That's up to you, to ensure that the ProcessQueue() method has the synchronization needed to guarantee that if any thread has modified the queue and caused this event to be raised, that that thread will not fail to initiate another round of processing should the first round not be able to observe the change.
Or put another way, you need to make sure that for any thread that is going to raise that event, either its change to the queue will be observed by the current processing operation, or that thread will initiate a new one.
There's not enough context in your question for anyone to be able to address that concern specifically. I will just point out that it's a common enough thing for someone to overlook when trying to implement this sort of system. IMHO, all the more reason to just have a dedicated thread using BlockingCollection<T> to consume elements added to the queue. :)
See also the related question How to avoid reentrancy with async void event handlers?. This is a slightly different question, in that the accepted answer causes each invocation of the event handler to result in the operation initiated by the event handler. Your scenario is simpler, since you simply want to skip initiation of a new operation, but you may still find some useful insight there.
I agree with Peter that abandoning event-based notifications is the best solution, and that you should move to a producer/consumer queue. However, I recommend one of the TPL Dataflow blocks instead of BlockingCollection<T>.
In particular, ActionBlock<T> should work quite nicely:
private readonly ActionBlock<T> notificationQueue = new ActionBlock<T>(async t =>
{
await ProcessQueueItem(t);
});
By default, TPL Dataflow blocks have a concurrency limit of 1.
I have a WPF (MVVM) project where I have multiple view-models, each with a button that launches different analyses on the same data source, which in this case is a file. The file cannot be shared, so if the buttons are pressed near the same time the second call will fail.
I need a way to queue the button clicks so that each analysis can be run sequentially, but I can't seem to get it to work. I tried using a static Semaphore, SemaphoreSlim and Mutex, but they appear to stop everything (the Wait() function appears to block the currently running analysis). I tried a lock() command with a static object but it didn't seem to block either event (I get the file share error). I also tried a thread pool (with a max concurrent thread count of 1), but it gives threading errors updating the UI (this may be solvable with Invoke() calls).
My question is what might be considered best practice in this situation with WPF?
EDIT: I created a mockup which exhibits the problem I'm having. It is at http://1drv.ms/1s4oQ1T.
What you need here is an asynchronous queue, so that you can enqueue these tasks without actually having anything blocking your threads. SemaphoreSlim actually has a WaitAsync method that makes creating such a queue rather simple:
public class TaskQueue
{
private SemaphoreSlim semaphore;
public TaskQueue()
{
semaphore = new SemaphoreSlim(1);
}
public async Task<T> Enqueue<T>(Func<Task<T>> taskGenerator)
{
await semaphore.WaitAsync();
try
{
return await taskGenerator();
}
finally
{
semaphore.Release();
}
}
public async Task Enqueue(Func<Task> taskGenerator)
{
await semaphore.WaitAsync();
try
{
await taskGenerator();
}
finally
{
semaphore.Release();
}
}
}
This allows you to enqueue operations that will be all executed sequentially, rather than in parallel, and without blocking any threads at any time. The operations can also be any type of asynchronous operation, whether that is CPU bound work in another thread, IO bound work, etc.
I would do two things to solve this problem:
First, encapsulate the analysis operations in a command pattern. If you aren't familiar with it, the simplest implementation is an interface with a single function Execute. When you want to perform an analysis operation, just create one of these. You could also use the built-in ICommand interface to help, but be aware that this interface has more to it than the generic command pattern.
Of course, creation is only half the battle, so after doing so I would add it to a BlockingCollection. This collection is .NET's solution to the Producer-Consumer problem. Have a background thread that consumes this collection (executing the command objects contained within) using a foreach on the collection's GetConsumingEnumerable method and your buttons will "feed" it.
foreach (var item in bc.GetConsumingEnumerable())
{
item.Execute();
}
MSDN for Blocking Collection: http://msdn.microsoft.com/en-us/library/dd267312(v=vs.110).aspx
Now, all the semaphores, waits, etc. are done for you, and you can just add an operation to the queue (if it needs to be a queue, consider using ConcurrentQueue as the backing collection for BlockingCollection) and return on the UI thread. The background thread will pick the task up and run it.
You will need to Invoke any UI updates from the background thread of course, no getting around that issue :).
I'd recommend a queue, in a scheduling object shared by the view-models, with a consumer task that waits on the queue to have an item added to it. When a button is pressed, the view-model adds a work item to the queue. The consumer task takes one item from the queue each time, does the analysis contained in the work item, and then checks the queue for another item, waiting for more work items to be added if there are no work items to be processed.
Need suggestion for best approach for Multi-threading in c# 3.0 (No Parallel or Task)
The situation is, I have a Queue with 500 items. At a particular time I can run only 10 threads (Max). Below is my code.
While (queue.Count > 0)
{
Thread[] threads = new Thread[no_of_threads];
for (int j = 0; j < no_of_threads; j++)
{
threads[j] = new Thread(StartProcessing);//StartProcessing Dequeue one item each time //for a single thread
threads[j].Start();
}
foreach (Thread objThread in threads)
{
objThread.Join();
}
}
Problem in this approach is, for an instance, if no_of_threads = 10 and out of them 9 threads are done with processing, and 1 thread is still working, I cannot come out of loop and delegate work to the free threads until all 10 threads are done.
I need at all the time 10 threads should work till the queue count > 0.
This is easily done with a Semaphore.
The idea is to create a semaphore with a maximum count of N, where N is the number of threads you allow. The loop waits on the semaphore and queues tasks as it acquires the semaphore.
Semaphore ThreadsAvailable = new Semaphore(10, 10);
while (Queue.Count > 0)
{
ThreadsAvailable.WaitOne();
// Must dequeue item here, otherwise you could run off the end of the queue
ThreadPool.QueueUserWorkItem(DoStuff, Queue.Dequeue());
}
// Wait for remaining threads to finish
int threadCount = 10;
while (threadCount != 0)
{
ThreadsAvailable.WaitOne();
--threadCount;
}
void DoStuff(object item)
{
ItemType theItem = (ItemType)item;
// process the item
StartProcessing(item);
// And then release the semaphore so another thread can run
ThreadsAvailable.Release();
}
The item is dequeued in the main loop because that avoids a race condition that otherwise is rather messy to handle. If you let the thread dequeue the item, then the thread has to do this:
lock (queue)
{
if (queue.Count > 0)
item = queue.Dequeue();
else
// There wasn't an item to dequeue
return;
}
Otherwise, the following sequence of events is likely to occur when there is only one item left in the queue.
main loop checks Queue.Count, which returns 1
main loop calls QueueUserWorkItem
main loop checks Queue.Count again, which returns 1 because the thread hasn't started yet
new thread starts and dequeues an item
main loop tries to dequeue an item and throws an exception because queue.Count == 0
If you're willing to handle things that way, then you're okay. The key is making sure that the thread calls Release on the semaphore before the thread exits. You can do that with explicitly managed threads, or with the ThreadPool approach that I posted. I just used ThreadPool because I find it easier than explicitly managing threads.
So all you need to handle this is a queue that is designed to be accessed from multilpe threads. Were you using .NET 4.0 I'd say use BlockingCollection. Not only will it work perfectly, but it's very efficient. You can rather trivially make your own class that is just a Queue with lock calls around all of the methods. It will work about as well, but it won't be as efficient. (It will likely be efficient enough for your purposes though, and a re-writing BlockingCollection "properly" would be quite hard.)
Once you have that queue each worker can just grab an item from that queue, process it, then ask the queue for another. When there are no more you don't need to worry about ending that thread; there's no more work it could do.
You should use ThreadPool which manages and optimizes threads for you
Once a thread in the pool completes its task, it is returned to a queue of waiting threads, where it can be reused. This reuse enables applications to avoid the cost of creating a new thread for each task.
Thread pools typically have a maximum number of threads. If all the threads are busy, additional tasks are put in queue until they can be serviced as threads become available.
It's better not to interfere into ThreadPool since it's enough smart to manage and allocate threads. But if you really need to do this, you can set the constraint of the maximum number of threads by using SetMaxThreads method
Instead of controlling the threads from the outside, let each thread consume data itself.
Pseudocode:
create 10 threads
thread code:
while elements in queue
get element from queue
process element
This is a simple producer-consumer scenario. You need a thread-safe queue like this one: Creating a blocking Queue<T> in .NET? - 10 threads can read and process job by job in a loop until the queue is empty.
Depending on how you fill the queue (prior to starting processing it or while processing it) you can end those threads as soon as the queue becomes empty or when you signal it to stop by means of a stop flag. In the latter case you probably need to wake the threads (eg with dummy jobs).
I need to build a process that listen in WCF for new tasks. (Async)
Every Task get Enqueue'ed (somehow).
What is the Best (Logical and Performance) way to loop the queue and Dequeue it.
I thought about:
while(true){
queue.Dequeue();
}
I assume that there are better ways to do that.
Thanks
Have a look at System.Collections.Concurrent namespace - there is thread-safe queue implementation viz. ConcurrentQueue - although, I suspect that your needs would be better served by BlockingCollection.
Blocking collection is essentially a thread-safe collection useful for producer-consumer scenario. In your case, WCF calls will act as producers that will add to the collection while the worker thread will act as consumer who would essentially take queued tasks from the collection. By using single consumer (and collection), you can ensure order of execution. If that's not important then you may able to use multiple consumer threads. (There are also AddAny and TakeAny static overloads that will allow you to use multiple collections (multiple queues) if that is the need.)
The advantage over while(true) approach would be avoidance of tight loop that will just consume CPU cycles. Apart from having thread-safe, this would also solve issue of synchronization between queuing and de-queuing threads.
EDIT:
Blocking Collection is really very simple to use. See below simple example - add task will invoked from say your WCF methods to queue up tasks while StartConsumer will be called during service start-up.
public class MyTask { ... }
private BlockingCollection<MyTask> _tasks = new BlockingCollection<MyTask>();
private void AddTask(MyTask task)
{
_tasks.Add(task);
}
private void StartConsumer()
{
// I have used a task API but you can very well launch a new thread instead of task
Task.Factory.StartNew(() =>
{
while (!_tasks.IsCompleted)
{
var task = _tasks.Take();
ProcessTask(task);
}
});
}
While stopping service, one need to invoke _tasks.CompleteAdding so that consumer thread will break.
Find more examples on MSDN:
http://msdn.microsoft.com/en-us/library/dd997306.aspx
http://msdn.microsoft.com/en-us/library/dd460690.aspx
http://msdn.microsoft.com/en-us/library/dd460684.aspx
Instead of the infinite loop, I would use events to synchronize the queue. Whenever the WCF call is made, add an element to the queue and send out a "AnElementHasBeenAddedEvent".
The Thread executing the queued tasks listens for that event and whenever it receives it, the queue will be emptied.
Make sure there is only one thread that does this job!
Advantages over the while(true) concept: You do not have a thread that constantly loops through the endless loop and thus eats resources. You only do as much work as needed.
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.