I have a Visual Studio 2008 C# .NET 3.5 project where a class listens for an event invocation from another class that is multithreaded. I need to ensure that my event only allows simultaneous access to a maximum of 10 threads. The 11th thread should block until one of the 10 finishes.
myobj.SomeEvent += OnSomeEvent;
private void OnSomeEvent(object sender, MyEventArgs args)
{
// allow up to 10 threads simultaneous access. Block the 11th thread.
using (SomeThreadLock lock = new SomeThreadLock(10))
{
DoUsefulThings(args.foo);
}
}
I do not have control over the other MyObj class, so I cannot implement a threadpool there.
What is the best way to implement this?
Thanks,
PaulH
You want the Semaphore class. It is, in short, a lock that only allows a specified number of callers through at any time.
Since you don't control the creation of threads, you do need to be careful about deadlock situations. Semaphores are not reentrancy-aware- if a given thread enters a semaphore more than once, it will take more than one slot. So if each of your caller's threads enters your semaphore more than once, there is the possibility of a deadlock.
Use a Semaphore for this. The constructor parameters are a little confusing to those just getting introduced to the class. The first parameter specifies the initial number of threads allowed through right now. The second parameter specifies the maximum number of threads allowed through at any given time.
myobj.SomeEvent += OnSomeEvent;
Semaphore semaphore = new Semaphore(10, 10);
private void OnSomeEvent(object sender, MyEventArgs args)
{
semaphore.WaitOne();
try
{
DoUsefulThings(args.foo);
}
finally
{
semaphore.Release();
}
}
It's customary to use a semaphore for this. Initialize it to 10 units. wait() for one unit before DoUsefulThings(), signal() one unit afterwards.
Related
Consider the following async function that modifies a non-thread-safe list:
async Task AddNewToList(List<Item> list)
{
// Suppose load takes a few seconds
Item item = await LoadNextItem();
list.Add(item);
}
Simply put: Is this safe?
My concern is that one may invoke the async method, and then while it's loading (either on another thread, or as an I/O operation), the caller may modify the list.
Suppose that the caller is partway through the execution of list.Clear(), for example, and suddenly the Load method finishes! What will happen?
Will the task immediately interrupt and run the list.Add(item); code? Or will it wait until the main thread is done with all scheduled CPU tasks (ie: wait for Clear() to finish), before running the code?
Edit: Since I've basically answered this for myself below, here's a bonus question: Why? Why does it immediately interrupt instead of waiting for CPU bound operations to complete? It seems counter-intuitive to not queue itself up, which would be completely safe.
Edit: Here's a different example I tested myself. The comments indicate the order of execution. I am disappointed!
TaskCompletionSource<bool> source;
private async void buttonPrime_click(object sender, EventArgs e)
{
source = new TaskCompletionSource<bool>(); // 1
await source.Task; // 2
source = null; // 4
}
private void buttonEnd_click(object sender, EventArgs e)
{
source.SetResult(true); // 3
MessageBox.Show(source.ToString()); // 5 and exception is thrown
}
No, its not safe. However also consider that the caller might also have spawned a thread and passed the List to its child thread before calling your code, even in a non async environment, which will have the same detrimental effect.
So; although not safe, there is nothing inherently thread-safe about receiving a List from a caller anyway - there is no way of knowing whether the list is actually being processed from other threads that your own.
Short answer
You always need to be careful using async.
Longer answer
It depends on your SynchronizationContext and TaskScheduler, and what you mean by "safe."
When your code awaits something, it creates a continuation and wraps it in a task, which is then posted to the current SynchronizationContext's TaskScheduler. The context will then determine when and where the continuation will run. The default scheduler simply uses the thread pool, but different types of applications can extend the scheduler and provide more sophisticated synchronization logic.
If you are writing an application that has no SynchronizationContext (for example, a console application, or anything in .NET core), the continuation is simply put on the thread pool, and could execute in parallel with your main thread. In this case you must use lock or synchronized objects such as ConcurrentDictionary<> instead of Dictionary<>, for anything other than local references or references that are closed with the task.
If you are writing a WinForms application, the continuations are put in the message queue, and will all execute on the main thread. This makes it safe to use non-synchronized objects. However, there are other worries, such as deadlocks. And of course if you spawn any threads, you must make sure they use lock or Concurrent objects, and any UI invocations must be marshaled back to the UI thread. Also, if you are nutty enough to write a WinForms application with more than one message pump (this is highly unusual) you'd need to worry about synchronizing any common variables.
If you are writing an ASP.NET application, the SynchronizationContext will ensure that, for a given request, no two threads are executing at the same time. Your continuation might run on a different thread (due to a performance feature known as thread agility), but they will always have the same SynchronizationContext and you are guaranteed that no two threads will access your variables at the same time (assuming, of course, they are not static, in which case they span across HTTP requests and must be synchronized). In addition, the pipeline will block parallel requests for the same session so that they execute in series, so your session state is also protected from threading concerns. However you still need to worry about deadlocks.
And of course you can write your own SynchronizationContext and assign it to your threads, meaning that you specify your own synchronization rules that will be used with async.
See also How do yield and await implement flow of control in .NET?
Assuming the "invalid acces" occures in LoadNextItem(): The Task will throw an exception. Since the context is captured it will pass on to the callers thread so list.Add will not be reached.
So, no it's not thread-safe.
Yes I think that could be a problem.
I would return item and add to the list on the main tread.
private async void GetIntButton(object sender, RoutedEventArgs e)
{
List<int> Ints = new List<int>();
Ints.Add(await GetInt());
}
private async Task<int> GetInt()
{
await Task.Delay(100);
return 1;
}
But you have to call from and async so I do not this this would work either.
I was wondering if there is any hybrid EventWaitHandle that will auto-reset it's state as AutoResetEvent is doing when .Set() is invoked and simultaneously will allow everybody who did .WaitOne() to pass the same as ManualResetEvent is doing.
The only one solution i came up is a very ugly one to use ManualResetEvent and to do the follwoing:
event.Set();
Thread.Sleep(100);
event.Reset();
What is the better way to do this ?
Thanks.
UPD:
Thansk to Hans I came up with the following solution.
Looks like it works:
class HybridWaitHandle
{
private bool signal = false;
private readonly object locker = new object();
private int blocked = 0;
void WaitOne()
{
lock (locker)
{
blocked++;
while (!signal) Monitor.Wait(locker);
blocked--;
if (blocked == 0)
signal = false;
}
}
void Set()
{
lock (locker)
{
signal = true;
Monitor.PulseAll(locker);
}
}
}
Use Monitor.PulseAll() instead. Known as "bounded buffer", sample code is here. Available in .NET 4 as BlockingCollection<>.
It's a bit hard to say without knowing more about how you're using it, but it sounds like a counted semaphore might fit the problem fairly well. You release the semaphore N times. That lets N threads run. When N threads have been released, the semaphore is reset. Note that technically, this isn't necessarily N separate threads -- it could be 1 thread released N times.
As such, if you need/want to assure that you're releasing N separate threads, you may (for one possibility) want to create 2 separate semaphores, alternating between the two for consecutive steps of the process. N threads wait on the first semaphore. When you release it N times, each thread runs, and then waits on the other semaphore. Eventually all the threads will be released by the first semaphore and run, which will reset that semaphore.
Then you can do the next processing step using the other semaphore.
Note, however, that much of this runs somewhat contrary to how threads tend to work best. You're forcing all the threads to remain in lock-step, but they're generally at their best if you just let them run as "freely" as possible.
I have a rather large class which contains plenty of fields (10+), a huge array (100kb) and some unmanaged resources. Let me explain by example
class ResourceIntensiveClass
{
private object unmaganedResource; //let it be the expensive resource
private byte[] buffer = new byte[1024 * 100]; //let it be the huge managed memory
private Action<ResourceIntensiveClass> OnComplete;
private void DoWork(object state)
{
//do long running task
OnComplete(this); //notify callee that task completed so it can reuse same object for another task
}
public void Start(object dataRequiredForCurrentTask)
{
ThreadPool.QueueUserWorkItem(DoWork); //initiate long running work
}
}
The problem is that the start method never returns after the 10000th iteration causing a stack overflow. I could execute the OnComplete delegate in another thread giving a chance for the Start method to return, but it requires using extra cpu time and resources as you know. So what is the best option for me?
Is there a good reason for doing your calculations recursively? This seems like a simple loop would do the trick, thus obviating the need for incredibly deep stacks. This design seems especially problematic as you are relying on main() to setup your recursion.
recursive methods can get out of hand quite fast. Have you looked into using Parallel Linq?
you could do something like
(your Array).AsParallel().ForAll(item => item.CallMethod());
you could also look into the Task Parallel Library (TPL)
with tasks, you can define an action and a continue with task.
The Reactive Framework (RX) on the other hand could handle these on complete events in an async manner.
Where are you changing the value of taskData so that its length can ever equal currentTaskIndex? Since the tasks you are assigning to the data are never changing, they are being carried out forever...
I would guess that the problem arises from using the pre-increment operator here:
if(c.CurrentCount < 10000)
c.Start(++c.CurrentCount);
I am not sure of the semantics of pre-increment in C#, perhaps the value passed to a method call is not what you expect.
But since your Start(int) method assigns the value of the input to this.CurrentCount as it's first step anyway, you should be safe replacing this with:
if(c.CurrentCount < 10000)
c.Start(c.CurrentCount + 1);
There is no point in assigning to c.CurrentCount twice.
If using the threadpool, I assume you are protecting the counters (c.CurrentCount), otherwise concurrent increments will cause more activity, not just 10000 executions.
There's a neat tool called a ManualResetEvent that could simplify life for you.
Place a ManualResetEvent in your class and add a public OnComplete event.
When you declare your class, you can wire up the OnComplete event to some spot in your code or not wire it up and ignore it.
This would help your custom class to have more correct form.
When your long process is complete (I'm guessing this is in a thread), simply call the Set method of the ManualResetEvent.
As for running your long method, it should be in a thread that uses the ManualResetEvent in a way similar to below:
private void DoWork(object state)
{
ManualResetEvent mre = new ManualResetEvent(false);
Thread thread1 = new Thread(
() => {
//do long running task
mre.Set();
);
thread1.IsBackground = true;
thread1.Name = "Screen Capture";
thread1.Start();
mre.WaitOne();
OnComplete(this); //notify callee that task completed so it can reuse same object for another task
}
I'm kind of new to threading in C# and had a couple of questions about what is out there:
What are the ways to implement threads in C#? (i.e. I can think of two off the top: backgroundWorker, Thread, etc)
How do you cause deadlock and if there is deadlock how do you get out of it (in C#)?
How does backgroundworker get implemented? It seems to have an underlying set of methods, but I'd like to know what those methods and instantiations are...
Thanks!
The definitive beginner's guide to threading in C# is here:
http://www.albahari.com/threading/
The documentation on BackgroundWorker, with a complete working example, is here: http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx
Deadlocks are explained here: http://www.albahari.com/threading/part2.aspx
Threads can be implemented in many ways. You can use them directly, pull them from a ThreadPool, or use them indirectly using the Task Parallel Library.
What are the ways to implement threads
in C#?
There are various different ways to take advantage of threading; some involving the explicit creation of threads while others take advantage of already running threads.
The Thread class itself.
Queue a work item in the thread pool.
Use the BackgroundWorker class.
Use the Task Parallel Library (TPL).
Use Parallel LINQ.
Use asynchronous delegates.
Use timers like System.Threading.Timer and System.Timers.Timer.
How do you cause deadlock and if there is deadlock how do you get out
of it (in C#)?
Here are 3 different ways you can cause a deadlock. This list is not exhaustive.
Call a blocking method from within a lock section.
In this example thread A acquires a lock and then immediately calls a blocking method while at the same time thread B attempts to acquire the same lock, but gets hung because thread A is waiting for thread B to signal the event before it will release the lock.
public class Example
{
ManualResetEvent m_Event = new ManualResetEvent(false);
void ThreadA()
{
lock (this)
{
m_Event.WaitOne();
}
}
void ThreadB()
{
lock (this)
{
m_Event.Set();
}
}
}
Acquire two locks out of order.
No explanation is needed here since this is a well known problem.
public class Example
{
private object m_LockObjectA = new object();
private object m_LockObjectB = new Object();
void ThreadA()
{
lock (m_LockObjectA) lock (m_LockObjectB) { }
}
void ThreadB()
{
lock (m_LockObjectB) lock (m_LockObjectA) { }
}
}
The lock-free deadlock.
This is one my favorite illustrations of a deadlock because no lock or blocking method is involved. The subtlety of the problem is enough to confound even those who are familiar with threading. The issue here is related to the absence of memory barriers. Thread A waits for thread B to set the signal flag while at the same time thread B waits for thread A to reset it, all the while neither thread is seeing the changes the other is making because the compiler, JIT, and hardware are free to optimize the reads and writes of the flag in manner that is non-intuitive.
public class Example
{
private bool m_Signal = false;
void ThreadA()
{
while (!m_Signal);
m_Signal = false;
}
void ThreadB()
{
m_Signal = true;
while (m_Signal);
}
}
How does backgroundworker get
implemented?
Here is a very simple step-by-step procedure to get you started.
Add an event handler that performs the actual work to the DoWork event.
Add an event handler to receive progress information to the ProgressChanged event.
Add an event handler that will be executed upon completion to the RunWorkerCompleted event.
Call RunWorkerAsync from the UI thread to start the background operation. This raises the DoWork event on a separate thread.
Call ReportProgress periodically from the DoWork event handler to publish new progress information. This raises the ProgressChanged event on the UI thread.
.net 4 offers parallel LINQ. This is very nice if you want to parallelize a side-effect free calculation which is easily expressible in functional/linq style.
For all common uses and purposes, use Thread. If you want to communicate from some thread to GUI, you may think of using BackgroundWorker, because it will automatically serialize (with Invoke() ) calls to GUI methods so you won't have GUI locking issues.
And as the deadlocks are concerned, don't worry about them. Deadlocks are possible only if you have 2 threads competing for the same set of resources, and I guess you won't tackle that just yet.
I would classify the answer into 3 sections. So with .net 4.0 all the examples above fall under 3 major categories:
1. Threads managed by .net thread pool (asynchronous delegate invocation, backgroundworker, etc)
2. The thread class - you have to manage the lifetime of the thread yourself
and finally Parallel Linq which requires multi core CPU.
I'd like to know how to implement the following restriction: One method in my Windows Service should not be called again before the earlier call has been finished. The method in question goes thru couple of database tables and it's very important that this process won't be called again before it's finished. I have a setting that defines how often my service will activate and under normal circumstances it never activates before the earlier call has been finished (because whole process should not take more than couple of minutes and the interval is set to 10 minutes) but thats not sure enough. I guess.
How to implement this?
You can use a named Mutex or a named Semaphore to ensure that only one holder of the Mutex/Semaphore is executing at once. As a commenter pointed out, keep in mind you must be careful not to abandon a mutex or improperly acquire/release a semaphore.
One way would be to use locking:
private readonly object myLock = new object();
private void MyMethod()
{
lock(myLock)
{
//code goes here
}
}
This ensures that this method can never be running more that once at a time.
I second the Mutex suggestion, but you might also want to take a look at transactions. Wrap your entire code in a transaction (this requires a using System.Transactions):
using(TransactionScope scope = new TransactionScope())
{
try
{
/* ... your current code here */
scope.Complete();
}
catch (Exception e)
{
/* Any appropriate error handling/logging here */
}
finally
{
}
}
A transactionscope automatically locks all related tables. You can reduce the restrictions and allow other processes to read, but not write to the data that your process is touching. You do this by passing options to the TransactionsScope constructor.
Well if all the code is localized you can set a boolean and check the boolean before executing the method, otherwise you can IPC and request the state before execution.
Some alternatives:
You can put a check in the call to check some flag or call Monitor.TryEnter and return with an error/do nothing if negative.
You can queue up calls (if you need this method to execute more than once) and only invoke when Monitor has been signaled.
If you don't mind blocking, and the method is on a separate thread, you can join the thread of the method you want to wait.
I'm sure there are others.
If you don't mind restricting one thread at a time to the entire object, then you can use:
Synchronization Contexts
Have your class inherit from ContextBoundObject
Apply a [Synchronization] attribute to the class.
The CLR will only allow one thread at a time to execute code per instance of this class. The others will block until the lock is released by the current thread.
This sounds like a serial workflow... Have you considered using a workflow framework?
If you want your function run with await/async
private static readonly SemaphoreSlim yourLock = new SemaphoreSlim(1, 1); //allow only 1 thread at time
...
private async Task<string> YourFunction() {
await yourLock.WaitAsync();
try
{
//your code go here
}
finally
{
yourLock.Release();
}
}