Related: How to catch exceptions from a ThreadPool.QueueUserWorkItem?
I am catching exceptions in background threads started by ThreadPool.QueueUserWorkItem(), and propagating them to the main thread via a shared instance variable.
The background threads do this:
try
{
... stuff happens here...
}
catch (Exception ex1)
{
lock(eLock)
{
// record only the first exception
if (_pendingException == null)
_pendingException = ex1;
}
}
There are multiple potential writers to _pendingException - multiple background threads - so I protect it with a lock.
In the main thread, must I take the lock before reading _pendingException? Or can I simply do this:
if (_pendingException != null)
ThrowOrHandle();
EDIT:
ps: I would prefer to NOT take the lock on the reader thread because it is on the hot path, and I'd be taking and releasing the lock very, very often.
You will not be able to get away this easy. You will lose exceptions if another thread throws it before the reader dealt with the existing one. What you need here is a synchronized queue:
try
{
... stuff happens here...
}
catch (Exception ex1)
{
lock(queue)
{
queue.Enqueue(ex1);
Monitor.PulseAll(queue);
}
}
And to process it:
while(!stopped)
lock (queue)
{
while (queue.Count > 0)
processException(queue.Dequeue());
Monitor.Wait(queue);
}
Reads and writes to references are atomic (See C# Spec) and I'm nearly certain that lock does create a memory barrier so yes what you are doing is probably safe.
But really just use the lock around your read. It's guaranteed to work; if you every see it accessed not in a lock you know something is wrong, if the lock is causing you performance issues then you're checking the flag way too often, and it's just the "right thing to do."
Even though you may only care about the first exception, you may still want to use lock for at least two reasons:
In multi-core CPUs, without making a variable volatile (or performing any memory barrier operation) , there might be a moment when threads running on different cores may see different values. (I am not sure calling lock(queue) in a worker thread will cause any memory barrier operation though). (update) Calling lock(queue) in a worker thread will cause memory barrier operation as pointed out by Eric in the comment below.
2. Please keep it mind that References are not addresses (by Eric Lippert) (if you are assuming references are 32-bit addresses in 32-bit CLR that can be read atomically). The implementation of references can be changed to some opaque structures that may not be read atomically in future release of CLR (even though I think it is not likely to happen in foreseeable future :)) and your code will break.
Related
I came across a ConcurrentDictionary implementation for .NET 3.5 (I'm so sorry I could find the link right now) that uses this approach for locking:
var current = Thread.CurrentThread.ManagedThreadId;
while (Interlocked.CompareExchange(ref owner, current, 0) != current) { }
// PROCESS SOMETHING HERE
if (current != Interlocked.Exchange(ref owner, 0))
throw new UnauthorizedAccessException("Thread had access to cache even though it shouldn't have.");
Instead of the traditional lock:
lock(lockObject)
{
// PROCESS SOMETHING HERE
}
The question is: Is there any real reason for doing this? Is it faster or have some hidden benefit?
PS: I know there's a ConcurrentDictionary in some latest version of .NET but I can't use for a legacy project.
Edit:
In my specific case, what I'm doing is just manipulating an internal Dictionary class in such a way that it's thread safe.
Example:
public bool RemoveItem(TKey key)
{
// open lock
var current = Thread.CurrentThread.ManagedThreadId;
while (Interlocked.CompareExchange(ref owner, current, 0) != current) { }
// real processing starts here (entries is a regular `Dictionary` class.
var found = entries.Remove(key);
// verify lock
if (current != Interlocked.Exchange(ref owner, 0))
throw new UnauthorizedAccessException("Thread had access to cache even though it shouldn't have.");
return found;
}
As #doctorlove suggested, this is the code: https://github.com/miensol/SimpleConfigSections/blob/master/SimpleConfigSections/Cache.cs
There is no definitive answer to your question. I would answer: it depends.
What the code you've provided is doing is:
wait for an object to be in a known state (threadId == 0 == no current work)
do work
set back the known state to the object
another thread now can do work too, because it can go from step 1 to step 2
As you've noted, you have a loop in the code that actually does the "wait" step. You don't block the thread until you can access to your critical section, you just burn CPU instead. Try to replace your processing (in your case, a call to Remove) by Thread.Sleep(2000), you'll see the other "waiting" thread consuming all of one of your CPUs for 2s in the loop.
Which means, which one is better depends on several factors. For example: how many concurrent accesses are there? How long the operation takes to complete? How many CPUs do you have?
I would use lock instead of Interlocked because it's way easier to read and maintain. The exception would be the case you've got a piece of code called millions of times, and a particular use case you're sure Interlocked is faster.
So you'll have to measure by yourself both approaches. If you don't have time for this, then you probably don't need to worry about performances, and you should use lock.
Your CompareExchange sample code doesn't release the lock if an exception is thrown by "PROCESS SOMETHING HERE".
For this reason as well as the simpler, more readable code, I would prefer the lock statement.
You could rectify the problem with a try/finally, but this makes the code even uglier.
The linked ConcurrentDictionary implementation has a bug: it will fail to release the lock if the caller passes a null key, potentially leaving other threads spinning indefinitely.
As for efficiency, your CompareExchange version is essentially a Spinlock, which can be efficient if threads are only likely to be blocked for short periods. But inserting into a managed dictionary can take a relatively long time, since it may be necessary to resize the dictionary. Therefore, IMHO, this isn't a good candidate for a spinlock - which can be wasteful, especially on single-processor system.
A little bit late... I have read your sample but in short:
Fastest to slowest MT sync:
Interlocked.* => This is a CPU atomic instruction. Can't be beat if it is sufficient for your need.
SpinLock => Uses Interlocked behind and is really fast. Uses CPU when wait. Do not use for code that wait long time (it is usually used to prevent thread switching for lock that do quick action). If you often have to wait more than one thread cycle, I would suggest to go with "Lock"
Lock => The slowest but easier to use and read than SpinLock. The instruction itself is very fast but if it can't acquire the lock it will relinquish the cpu. Behind the scene, it will do a WaitForSingleObject on a kernel objet (CriticalSection) and then Window will give cpu time to the thread only when the lock will be freed by the thread that acquired it.
Have fun with MT!
The docs for the Interlocked class tell us it
"Provides atomic operations for variables that are shared by multiple threads. "
The theory is an atomic operation can be faster than locks. Albahari gives some further details on interlocked operations stating they are faster.
Note that Interlocked provides a "smaller" interface than Lock - see previous question here
Yes.
The Interlocked class offer atomic operations which means they do not block other code like a lock because they don't really need to.
When you lock a block of code you want to make sure no 2 threads are in it at the same time, that means that when a thread is inside all other threads wait to get in, which uses resources (cpu time and idle threads).
The atomic operations on the other hand do not need to block other atomic operations because they are atomic. It's conceptually a one CPU operation, the next ones just go in after the previous, and you're not wasting threads on just waiting. (By the way, that's why it's limited to very basic operations like Increment, Exchange etc.)
I think a lock (which is a Monitor underneath) uses interlocked to know if the lock is already taken, but it can't know that the actions inside it can be atomic.
In most cases, though, the difference is not critical. But you need to verify that for your specific case.
Interlocked is faster - already explained in other comments and you can also define the logic of how the wait is implemented e.g. spinWait.spin(), spinUntil, Thread.sleep etc once the lock fails the first time.. Also, if your code within the lock is expected to run without possibility of crash (custom code/delegates/resource resolution or allocation/events/unexpected code executed during the lock) unless you are going to be catching the exception to allow your software to continue execution, "try" "finally" is also skipped so extra speed there. lock(something) makes sure if you catch the exception from outside to unlock that something, just like "using" makes sure (C#) when the execution exits the execution block for whatever reason to dispose the "used" disposable object.
One important difference between lock and interlock.CompareExhange is how it can be used in async environments.
async operations cannot be awaited inside a lock, as they can easily occur in deadlocks if the thread that continues execution after the await is not the same one that originally acquired the lock.
This is not a problem with interlocked however, because nothing is "acquired" by a thread.
Another solution for asynchronous code that may provide better readability than interlocked may be semaphore as described in this blog post:
https://blog.cdemi.io/async-waiting-inside-c-sharp-locks/
I have a method whom access myst be synchronized allowing only one thread at once to go though it. Here is my current implementation:
private Boolean m_NoNeedToProceed;
private Object m_SynchronizationObject = new Object();
public void MyMethod()
{
lock (m_SynchronizationObject)
{
if (m_NoNeedToProceed)
return;
Now I was thinking about changing it a little bit like so:
private Boolean m_NoNeedToProceed;
private Object m_SynchronizationObject = new Object();
public void MyMethod()
{
if (m_NoNeedToProceed)
return;
lock (m_SynchronizationObject)
{
Shouldn't it be better to do a quick return before locking it so that calling threads can proceed without waiting for the previous one to complete the method call?
Shouldn't it be better to do a quick return before locking it...
No. A lock is is not just a mutual-exclusion mechanism, it's also a memory barrier1. Without a lock, you could introduce a data race if any of the concurrent threads tries to modify the variable2.
BTW, locks have a good performance when there is no contention, so you wouldn't be gaining much performance anyway. As always, refrain from making assumptions about performance, especially this "close to the metal". If in doubt, measure!
...so that calling threads can proceed without waiting for the previous one to complete the method call?
This just means you are holding the lock for longer than necessary. Release the lock as soon as the shared memory no longer needs protection (which might be sooner than the method exit), and you won't need to try to artificially circumvent it.
1 I.e. triggers a cache coherency mechanism so all CPU cores see the "same" memory.
2 For example, one thread writes to the variable, but that change lingers in one core's write buffer for some time, so other threads on other cores don't see it immediately.
Yes, as long as m_NoNeedToProceed doesn't have any race conditions associated with it.
If the method takes a long time to run, and some threads do not need to actually access the critical sections of the method. Then it would be best to let them return early without getting the lock.
Yes it's better to that before you lock.
Make m_NoNeedToProceed volatile
Just a disclaimer: volatile doesn't make it thread safe. It just causes a barrier to check if the value has changed in another processor.
I need to develop a multithreaded Azure worker role in C# - create multiple threads, feed requests to them, each request might require some very long time to process (not my code - I'll call a COM object to do actual work).
Upon role shutdown I need to gracefully stop processing. How do I do that? Looks like if I just call Thread.Abort() the ThreadAbortException is thrown in the thread and the thread can even use try-catch-finally (or using) to clean up resources. This looks quite reliable.
What bothers me is that my experience is mostly C++ and it's impossible to gracefully abort a thread in an unmanaged application - it will just stop without any further processing and this might leave data in inconsistent state. So I'm kind of paranoid about whether anything like that happens in case I call Thread.Abort() for a busy thread.
Is it safe practice to use Thread.Abort() together with handling ThreadAbortException? What should I be aware of if I do that?
Is using Thread.Abort() and handling ThreadAbortException in .NET safe practice?
TL;DR version: No, isn't.
Generally you're safe when all type invariants (whether explicitly stated or not) are actually true. However many methods will break these invariants while running, only to reach a new state when they are again true at the end. If the thread is idle in a state with invariants held you'll be OK, but in that case better to use something like an event to signal the thread to exit gracefully (ie. you don't need to abort).
An out-of-band exception1 thrown in a thread while in such a invariants-not-true, ie. invalid, state is where the problems start. These problems include, but are certainly not limited to, mutually inconsistent field and property values (data structures in an invalid state), locks not exited, and events representing "changes happened" not fired.
In many cases it is possible to deal with these in clean up code (eg. a finally block), but then consider what happens when the out-of-band exception occurs in that clean up code? This leads to clean up code for the clean up code. But then that code is it self vulnerable so you need clean up code for the clean up code of the clean up code… it never ends!
There are solutions, but they are not easy to design (and tends to impact your whole design), and even harder to test—how to re-create all the cases (think combinatorial explosion). Two possible routes are:
Work on copies of state, update the copies and then atomically swap current for new state. If there is an out-of-band exception then the original state remains (and finalisers can clean up the temporary state).
This is rather like the function of database transactions (albeit RDBMSs work with locks and transaction log files).
It is also similar to the approaches to achieving the "strong exception guarantee" developed in the C++ community in response to a paper questioning if exceptions could ever be safe (C++ of course has no GC/finaliser queue to clean up discarded objects). See Herb Sutters "Guru of the Week #8: CHALLENGE EDITION: Exception Safety" for the solution.
In practice this is hard to achieve unless your state can be encapsulated in a single reference.
Look at "Constrained Execution Regions", but not the limitations on what you can do in these cases. (MSDN Magazine had an introductory article (introduction to the subject, not introductory level), from .NET 2 beta period2).
In practice if you have to do this, using approach #2 to manage the state change under #1 is probably the best approach, but getting it right, and then validating that it is correct (and the correctness is maintained) is hard.
Summary: It's a bit like optimisation: rule 1: don't do it; rule 2 (experts only): don't do it unless you have no other option.
1 A ThreadAbortException is not the only such exception.
2 So details have possibly changed.
One example where it's problematic to abort a thread.
using(var disposable=new ClassThatShouldBeDisposed())
{
...
}
Now the Thread abortion happes after the constructor of the class has finished but before the assignment to the local variable. So it won't be disposed. Eventually the finalizer will run, but that can be much later.
Deterministic disposing and thread abortion don't work well together. The only way I know to get safe disposing when using thread abortion is putting all the critical code inside a finally clause.
try
{//Empty try block
}
finally
{
//put all your code in the finally clause to fool thread abortion
using(var disposable=new ClassThatShouldBeDisposed())
{
...
}
}
This works because thread abortion allows finally code to execute. Of course this implies that the thread abortion will simply not work until the code leaves the finally block.
One way to get your code to work correctly with thread abortion is using the following instead of the using statement. Unfortunately it's very ugly.
ClassThatShouldBeDisposed disposable=null;
try
{
try{}finally{disposable=new ClassThatShouldBeDisposed();}
//Do your work here
}
finally
{
if(disposable!=null)
disposable.Dispose();
}
Personally I just assume threads never get aborted(except when unloading the AppDomain) and thus write normal using based code.
It's very difficult to handle the TheadAbortException correctly, because it can be thrown in the middle of whatever code the thread is executing.
Most code is written with the assumption that some actions, for example int i = 0; never causes an exception, so the critical exception handling is only applied to code that actually can cause an exception by itself. When you abort a thread, the exception can come in code that is not prepared to handle it.
The best practice is to tell the thread to end by itself. Create a class for the method that is running the thread, and put a boolean variable in it. Both the code that started the thread and the method running the thread can access the variable, so you can just switch it to tell the thread to end. The code in the thread of course have to check the value periodically.
Thread.Abort is an unsafe way of killing the thread.
It rises an asynchronous ThreadAbortException which is a special exception that can be caught, but it will automatically be raised again at the end of the catch block
It can leave the state corrupted, and your application becomes unstable
TAE is raised in the other thread
The best practise is to use wrappers that support work cancellation, such as the Task class or use volatile bool. Instead of Thread.Abort consider using Thread.Join which will block the calling thread until the working thread is disposed of.
Some links:
- How To Stop a Thread in .NET (and Why Thread.Abort is Evil)
- Managed code and asynchronous exception hardening
- The dangers of Thread.Abort
As others have mentioned, aborting a thread is probably not a good idea. However, signalling a thread to stop with a bool may not work either, because we have no guarantee that the value of a bool will be synchronized across threads.
It may be better to use an event:
class ThreadManager
{
private Thread thread = new Thread(new ThreadStart(CallCOMMethod));
private AutoResetEvent endThread = new AutoResetEvent(false);
public ThreadManager()
{
thread.Start();
}
public StopThread()
{
endThread.Set();
}
private void CallCOMMethod()
{
while (!endThread.WaitOne())
{
// Call COM method
}
}
}
Since the COM method is long running you may just need to "bite the bullet" and wait for it to complete its current iteration. Is the information computed during the current iteration of value to the user?
If not, one option my be:
Have the ThreadManager itself run on a separate thread from the UI which checks for the stop notification from the user relatively often.
When the user requests that the long running operation be stopped, the UI thread can immediately return to the user.
The ThreadManager waits for the long running COM operation to complete its current iteration, then it throws away the results.
It's considered best practice to just let the thread's method return:
void Run() // thread entry function
{
while(true)
{
if(somecondition) // check for a terminating condition - usually "have I been disposed?"
break;
if(workExists)
doWork();
Thread.Sleep(interval);
}
}
Please get simple idea from here as for your requirement, check thead isalive property, then abort your thread.............................................................
ThreadStart th = new ThreadStart(CheckValue);
System.Threading.Thread th1 = new Thread(th);
if(taskStatusComleted)
{
if (th1.IsAlive)
{
th1.Abort();
}
}
private void CheckValue()
{
//my method....
}
When should locks be used? Only when modifying data or when accessing it as well?
public class Test {
static Dictionary<string, object> someList = new Dictionary<string, object>();
static object syncLock = new object();
public static object GetValue(string name) {
if (someList.ContainsKey(name)) {
return someList[name];
} else {
lock(syncLock) {
object someValue = GetValueFromSomeWhere(name);
someList.Add(name, someValue);
}
}
}
}
Should there be a lock around the the entire block or is it ok to just add it to the actual modification? My understanding is that there still could be some race condition where one call might not have found it and started to add it while another call right after might have also run into the same situation - but I'm not sure. Locking is still so confusing. I haven't run into any issues with the above similar code but I could just be lucky so far. Any help above would be appriciated as well as any good resources for how/when to lock objects.
You have to lock when reading too, or you can get unreliable data, or even an exception if a concurrent modification physically changes the target data structure.
In the case above, you need to make sure that multiple threads don't try to add the value at the same time, so you need at least a read lock while checking whether it is already present. Otherwise multiple threads could decide to add, find the value is not present (since this check is not locked), and then all try to add in turn (after getting the lock)
You could use a ReaderWriterLockSlim if you have many reads and only a few writes. In the code above you would acquire the read lock to do the check and upgrade to a write lock once you decide you need to add it. In most cases, only a read lock (which allows your reader threads to still run in parallel) would be needed.
There is a summary of the available .Net 4 locking primitives here. Definitely you should understand this before you get too deep into multithreaded code. Picking the correct locking mechanism can make a huge performance difference.
You are correct that you have been lucky so far - that's a frequent feature of concurrency bugs. They are often hard to reproduce without targeted load testing, meaning correct design (and exhaustive testing, of course) is vital to avoid embarrassing and confusing production bugs.
Lock the whole block before you check for the existence of name. Otherwise, in theory, another thread could add it between the check, and your code that adds it.
Actually locking just when you perform the Add really doesn't do anything at all. All that would do is prevent another thread from adding something simultaneously. But since that other thread would have already decided it was going to do the add, it would just try to do it anyway as soon as the lock was released.
If a resource can only be accessed by multiple threads, you do not need any locks.
If a resource can be accessed by multiple threads and can be modified, then all accesses/modifications need to be synchronized. In your example, if GetValueFromSomeWhere takes a long time to return, it is possible for a second call to be made with the same value in name, but the value has not been stored in the Dictionary.
ReaderWriterLock or the slim version if you under 4.0.
You will aquire the reader lock for the reads (will allow for concurrent reads) and upgrade the lock to the writer lock when something is to write (will allow only one write at the time and will block all the reads until is done, as well as the concurrent write-threads).
Make sure to release your locks with the pattern to avoid deadlocking:
void Write(object[] args)
{
this.ReaderWriterLock.AquireWriteLock(TimeOut.Infinite);
try
{
this.myData.Write(args);
}
catch(Exception ex)
{
}
finally
{
this.ReaderWriterLock.RelaseWriterLock();
}
}
In a c# threading app, if I were to lock an object, let us say a queue, and if an exception occurs, will the object stay locked? Here is the pseudo-code:
int ii;
lock(MyQueue)
{
MyClass LclClass = (MyClass)MyQueue.Dequeue();
try
{
ii = int.parse(LclClass.SomeString);
}
catch
{
MessageBox.Show("Error parsing string");
}
}
As I understand it, code after the catch doesn't execute - but I have been wondering if the lock will be freed.
I note that no one has mentioned in their answers to this old question that releasing a lock upon an exception is an incredibly dangerous thing to do. Yes, lock statements in C# have "finally" semantics; when control exits the lock normally or abnormally, the lock is released. You're all talking about this like it is a good thing, but it is a bad thing! The right thing to do if you have a locked region that throws an unhandled exception is to terminate the diseased process immediately before it destroys more user data, not free the lock and keep on going.
Look at it this way: suppose you have a bathroom with a lock on the door and a line of people waiting outside. A bomb in the bathroom goes off, killing the person in there. Your question is "in that situation will the lock be automatically unlocked so the next person can get into the bathroom?" Yes, it will. That is not a good thing. A bomb just went off in there and killed someone! The plumbing is probably destroyed, the house is no longer structurally sound, and there might be another bomb in there. The right thing to do is get everyone out as quickly as possible and demolish the entire house.
I mean, think it through: if you locked a region of code in order to read from a data structure without it being mutated on another thread, and something in that data structure threw an exception, odds are good that it is because the data structure is corrupt. User data is now messed up; you don't want to try to save user data at this point because you are then saving corrupt data. Just terminate the process.
If you locked a region of code in order to perform a mutation without another thread reading the state at the same time, and the mutation throws, then if the data was not corrupt before, it sure is now. Which is exactly the scenario that the lock is supposed to protect against. Now code that is waiting to read that state will immediately be given access to corrupt state, and probably itself crash. Again, the right thing to do is to terminate the process.
No matter how you slice it, an exception inside a lock is bad news. The right question to ask is not "will my lock be cleaned up in the event of an exception?" The right question to ask is "how do I ensure that there is never an exception inside a lock? And if there is, then how do I structure my program so that mutations are rolled back to previous good states?"
First; have you considered TryParse?
in li;
if(int.TryParse(LclClass.SomeString, out li)) {
// li is now assigned
} else {
// input string is dodgy
}
The lock will be released for 2 reasons; first, lock is essentially:
Monitor.Enter(lockObj);
try {
// ...
} finally {
Monitor.Exit(lockObj);
}
Second; you catch and don't re-throw the inner exception, so the lock never actually sees an exception. Of course, you are holding the lock for the duration of a MessageBox, which might be a problem.
So it will be released in all but the most fatal catastrophic unrecoverable exceptions.
yes, that will release properly; lock acts as try/finally, with the Monitor.Exit(myLock) in the finally, so no matter how you exit it will be released. As a side-note, catch(... e) {throw e;} is best avoided, as that damages the stack-trace on e; it is better not to catch it at all, or alternatively: use throw; rather than throw e; which does a re-throw.
If you really want to know, a lock in C#4 / .NET 4 is:
{
bool haveLock = false;
try {
Monitor.Enter(myLock, ref haveLock);
} finally {
if(haveLock) Monitor.Exit(myLock);
}
}
"A lock statement is compiled to a call to Monitor.Enter, and then a try…finally block. In the finally block, Monitor.Exit is called.
The JIT code generation for both x86 and x64 ensures that a thread abort cannot occur between a Monitor.Enter call and a try block that immediately follows it."
Taken from:
This site
Just to add a little to Marc's excellent answer.
Situations like this are the very reason for the existence of the lock keyword. It helps developers make sure the lock is released in the finally block.
If you're forced to use Monitor.Enter/Exit e.g. to support a timeout, you must make sure to place the call to Monitor.Exit in the finally block to ensure proper release of the lock in case of an exception.
Your lock will be released properly. A lock acts like this:
try {
Monitor.Enter(myLock);
// ...
} finally {
Monitor.Exit(myLock);
}
And finally blocks are guaranteed to execute, no matter how you leave the try block.