Is ReaderWriterLockSlim resistant to ThreadAbortException? - c#

I would like to check whether following code is resistant against ThreadAbortException and will not lead into orphan lock. If it is not, what is the best pattern to avoid orphan locks here?
ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();
public void DoStaff()
{
_lock.EnterWriteLock();
//Is this place where ThreadAbotException can corrupt my code, or is there JIT optimalization which prevent this from happening???
try
{
...
}
finally
{
_lock.ExitWriteLock();
}
}
According following link http://chabster.blogspot.cz/2013/07/a-story-of-orphaned-readerwriterlockslim.html, there is (or at least there was) possible way how to create orphan locks but I was running sample code for a while without any luck.
I am using .NET 4.0
Is there any difference between behavior in Debug and Release?

Yes, ThreadAbortException could occur there, in which case the try wouldn't be entered and therefore you would never exit the write lock.
There's no good general solution to the problem. Which is why Eric Lippert (among others) says that Locks and exceptions do not mix.
You're asking specifically about ThreadAbortException, which leads me to believe that you're contemplating using Thread.Abort for some kind of threading control in your application. I urge you to reconsider. If you want the ability to cancel your threads, you should use Cancellation or something similar. Using Thread.Abort in any other than the most dire circumstances is a horrifically bad idea. It certainly should not be part of your program's overall design.

In order for code which uses a locking primitive to be robust in the face of thread aborts, it is necessary that every lock-acquisition and lock-release request pass, or be performed through, an unshared token which can be given "ownership" the lock. Depending upon the design of the locking API, the token may be an object of some specific type, an arbitrary Object, or a variable passed as a ref parameter. It's imperative, however, that the token be created and stored by some means before the lock is acquired, so that if the token gets created but the store fails, the token may be abandoned without difficulty. Unfortunately, although monitor locks have added (in .NET 4.0) overloads of Monitor.Enter and Monitor.TryEnter which use ref bool as a token, I know of no equivalent for reader-writer locks.
If one wants abort-safe reader-writer lock functionality, I would suggest one would need a class which was designed around that; it should keep track of what threads hold reader or writer access and, rather than relying upon threads to release locks, it should, when waiting for a lock to be released, make sure the thread holding it is still alive. If a thread dies while holding read access, it should be released. If a thread dies while holding right access, any pending or future attempts to acquire the lock should throw an immediate exception.
Otherwise, there are some tricks via which a block of code can be protected against Thread.Abort(). Unfortunately, I don't know any clean way to bracket the code around a lock-acquisition request in such a way that Abort will work when the request itself can be cleanly aborted without having succeeded, but will be deferred if the request succeeds.
There are ways via which a framework could safely allow a thread which is in an endless loop to be killed by another thread, but designing mechanisms which could be used safely would require more effort than was put into Thread.Abort().

Related

ReaderWriterLockSlim questions

In his answer here, https://stackoverflow.com/a/19664437/4919475
Stephen Cleary mentioned
ReaderWriterLockSlim is a thread-affine lock type, so it usually
cannot be used with async and await.
What did he mean by "usually"? When can ReaderWriterLockSlim be used?
Also, I've read here http://joeduffyblog.com/2007/02/07/introducing-the-new-readerwriterlockslim-in-orcas/ that ReaderWriterLockSlim has different quirks, but this article is from 2007. Did it change since then?
I guess you've posted a question that only Cleary can answer, because you want to know what he means.
In the meantime, the obvious inference from his statement is that you can get away with using ReaderWriterLockSlim with async/await in any situation where you are able to guarantee the same thread that acquired the lock will also be able to release it.
For example, you could imagine code like this:
private readonly ReaderWriterLockSlim _rwls = new ReaderWriterLockSlim();
async void button1_Click(object sender, EventArgs e)
{
_rwls.EnterWriteLock();
await ...;
_rwls.ExitWriteLock();
}
In the above, because the Click event will be raised in a thread where await will return to, you can acquire the lock, execute the await, and still get away with releasing the lock in the continuation, because you know it'll be the same thread.
In many other uses of async/await, the continuation is not guaranteed to be in the thread in which the method yielded, and so it wouldn't be allowed to release the lock having acquired it previous to the await. In some cases, this is explicitly intentional (i.e. ConfigureAwait(false)), in other cases it's just a natural outcome of the context of the await. Either way, those scenarios aren't compatible with ReaderWriterLockSlim the way the Click example would be.
(I am intentionally ignoring the larger question of whether it's a good idea to acquire a lock and then hold it for the duration of a potentially long-running asynchronous operation. That is, as they say, "a whole 'nother ball o' wax" .)
Addendum:
A "short" comment, which is too long to be an actual comment, regarding the "larger question" I am ignoring…
The "larger question" is fairly broad and highly context-dependent. It's why I didn't address it. The short version is in two parts:
In general, locks should be held for brief periods of time, but in general asynchronous operations are known to be potentially long in duration, so the two are mutually disagreeable. Locks are a necessary evil when doing concurrent operations, but they will always to some extent negate the benefit of doing things concurrently, because they have the effect of serializing otherwise-concurrent operations.The longer you hold a lock, the greater the likelihood of one or more threads getting blocked waiting for something, serializing whatever work they have. They are all waiting on the same lock, so even once the long-running lock is released, they still will all have to work in order, not concurrently. It's a bit like a traffic jam where a long queue of cars is waiting for a construction truck to finish blocking the road…even once the truck is out of the way, it will take some significant time to clear the jam.I would not say is inherently bad to hold a lock during an asynchronous operation — that is, I can imagine carefully thought-out scenarios where it would be okay — but it very often will undermine other implementation goals, and can in some cases completely undo a design meant to be heavily concurrent, especially when done without great care.
Semantically it's easy to make a mistake, i.e. with await you know the lock remains for the duration, but "fire-and-forget" is not uncommon, and would lead to the code appearing to lock while an asynchronous operation is occurring, but in reality it not (see the Stack Overflow question What happens to a lock during an Invoke/BeginInvoke? (event dispatching) for an example of someone who did exactly this, and didn't even realize it). One methodology for avoiding buggy code is to simply avoid patterns of coding known to potentially lead to bugs.Again, if one is careful enough, one can avoid the bug. But it is generally better to simply change the implementation to use a less tricky approach, and to be in the habit of doing so.
I noticed over on this question that you had asked:
Can you explain what you mean by "arbitrary code"?
I believe this note highlights an important aspect to "the larger question" which I will try--briefly, as I am also pressed for time--to address here. One of the main concerns here is that an await statement cannot guarantee the Task it awaits will run within the same context (particularly, in the case of thread-affine locks, on the same thread) as the calling code; this, in fact, would defeat much of the purpose of the Task promise.
Let's say the Task you await, somewhere down the line, awaits a Task created using Task.Run, is otherwise on another thread, or has yielded the current thread to await some background resource (like disk or network I/O). Under these conditions there are at least two unexpected behaviors which would be easy to accidentally come across:
If the code executing in the other thread attempts to obtain the same lock as the calling code that is awaiting it; the calling thread owns the lock and since the sub-task is executing on a different thread it cannot obtain the lock until the calling thread releases it, which it will not do because it is awaiting the sub-task that has not completed. If the second attempt to lock was on the same thread as the first, the lock would recognize that this thread has already acquired the lock and would allow the second lock attempt to proceed. Since they are not on the same thread this becomes a self-dependent deadlock and will either halt both the calling thread and the sub-task or will timeout, depending on the locking methods used. Most other deadlocks require using 2 or more locks in differing order across multiple code paths where each path holds a lock the other is waiting on.
If the calling thread is the UI thread (or some other context with a message pump which can continue processing requests while a previous request is awaiting asynchronous behavior), assuming it awaits a Task executing in another thread which takes long enough to process that the message pump begins processing another message (like another click to the same button, or any other "arbitrary code" which might want the same lock), that new message is executing on the same thread which owns the lock and is therefore allowed to proceed even though the previous Task has not completed, thus allowing arbitrary access to resources that are supposed to be synchronized.
While the former could cause your application or some component of it to lock up, the latter of these issues can yield very unexpected results and be especially tricky to troubleshoot. Similar conditions exist for all thread-affine locking mechanisms (like Monitor which is the underlying implementation of the lock keyword). Hope that helps.
If you're interested in more about parallelism patterns in C#, I might recommend the free Threading in C# e-book (which is actually an excerpt from the otherwise excellent book "C# in a Nutshell")

Best way to handle multi threaded applications from running code concurrently

I have an automatic betting BOT.
I use a Windows Service and timers to set off a job every 30 seconds in its own thread that takes bets from the DB, loops through and places them.
However in certain occurrences when the job is too long (over 30 seconds) I can get the same bet being placed twice using the same BetPK (unique ID) as the job for placing it runs at the same time as a previously started thread.
I am using C#, NET 4, VS 2012.
At the moment I set a "locked" flag in a table when the job to place bets runs and then unset it on finishing. So if another job runs and the job is locked it will return ASAP. However this is relying on the DB and network traffic.
What would be the best way in C# to prevent a job started by a timer thread from clashing with a previously started thread. I am thinking I could set a flag IN the service controller that spawns the threads so if a job is running another one won't spawn.
However I would like to learn the correct way to handle multi threaed clashes like this. I just lost a couple of hundred pounds today due to 2 LAY bets being placed at exactly the same time. As only one record existed for the Bet, the last bet placed had the Betfair ID updated so I had no clue about the duplicate until I checked Betfairs own page.
I do already do checks to see if the bet has already been placed before trying to place it but in cases where the "placebet" method is running on the same Bet record at exactly the same time then this is no good.
Any help much appreciated.
Thanks
No, the best solution is to keep the locks in the database. The app should be as stateless as possible. You already have a great solution.
Locking inside of your app is error prone and the errors are catastrophic (deadlock, the app stops to work until manually restarted). Locking using the database is much easier, and errors are recoverable.
Just get the locking with the database right. Ask a new question where you post details on what you're doing. I recommend that you XLOCK any betting jobs that you're working on. That way they can only be executed once. Use the power of database locks and transactions to make this work. This is by far easier than app-level threading.
You could always try implementing a db like Redis (redis.io) that offers built in POP functions (http://redis.io/commands/lpop). Redis has a C# client and is super useful for any kind of app where speed is crucial as it keeps the entire db in memory. It's also single threaded which makes it easy to implement distributors for multi-consumer type applications.
I'd also recommend checking out http://kkovacs.eu/cassandra-vs-mongodb-vs-couchdb-vs-redis as it lays out the pros and cons for Redis and other dbs. Might help you make future db decisions.
Old question, I know, but I wanted to throw this out there for anybody that stumbles across it.
C# (and presumably VB.NET) offers a couple of nice options for handling thread synchronization. You can use the lock keyword to block execution until a given lock is available, or Monitor.TryEnter() if you want to specify a timeout (possibly immediately) for taking the lock.
For either of these approaches, you need an object to use for locking. Pretty much any object will do; if you aren't synchronizing access to some object itself (collection, database connection, whatever), you can even just instantiate a throwaway object. For a polling timer, the latter is typical.
First, make sure you have an object to use for synchronization:
public class DatabasePollingClass {
object PollingTimerLock = new object();
...
Now, if you want the polling threads to block indefinitely waiting for their turn, use the lock keyword:
public class DatabasePollingClass {
object PollingTimerLock = new object();
...
protected void PollingTimerCallback() {
lock (PollingTimerLock) {
//Useful stuff here
}
}
}
Only a single thread will be allowed within the lock (PollingTimerLock) block of code at a time. All other threads will wait indefinitely, then resume executing as soon as they can acquire the lock for themselves.
However, you probably don't want that behavior. If you'd rather have the subsequent threads abort immediately (or after a short wait) if another polling thread is still running, you can use Monitor.TryEnter() when taking the lock. This does require slightly more caution, however:
public class DatabasePollingClass {
object PollingTimerLock = new object();
...
protected void PollingTimerCallback() {
if (Monitor.TryEnter(PollingTimerLock)) { //Acquires lock on PollingTimerLock object
try {
//Useful stuff here
} finally {
//Releases lock.
//You MUST do this in a finally block! (See below.)
Monitor.Exit(PollingTimerLock);
}
} else {
Console.WriteLine("Warning: Polling timer overlap. Skipping.");
}
}
}
The additional caution stems from the fact that, unlike the lock keyword, Monitor.TryEnter() requires you to manually release the lock when you're finished with it. In order to guarantee that this happens, you need to wrap your whole critical section in a try block, and release the lock in the finally block. This is to ensure that the lock will be released, even if the polling method fails or returns early. If the method returned without releasing the lock, your program would effectively be hung, as no further threads would be able to acquire the lock.
Another option, which doesn't use locking mechanisms, would be to configure your Timer without a repeat period, i.e. a one-shot Timer. At the end of your polling method, you would dispose the old Timer, and set a new one (you would also need to do this within a finally block to guarantee that the Timer gets reset by the end of the method). This approach would be useful if you want to poll the database at a certain interval since the end of the previous polling. It's a subtle distinction, but it also solves the problem of concurrent polling attempts.
Note that this is a really simple thread concurrency example. As long as all of your locking is happening on threads separate from your UI thread (the message pump itself can become a point of contention), and you're only ever locking a single object, you shouldn't have to worry too much about deadlocks. Those can be really unpleasant to debug; the symptom is usually "application stops responding, and now you get to guess which threads are waiting on what".

Revisiting Thread.Abort() - is it safe?

MSDN on migrating legacy multithreaded applications (from this page on exception handling in threads):
In general, the change will expose previously unrecognized programming problems so that they can be fixed. In some cases, however, programmers might have taken advantage of the runtime backstop, for example to terminate threads. Depending on the situation, they should consider one of the following migration strategies:
Restructure the code so the thread exits gracefully when a signal is received.
Use the Thread.Abort method to abort the thread.
If a thread must to be stopped so that process termination can proceed, make the thread a background thread so that it is automatically terminated on process exit.
In all cases, the strategy should follow the design guidelines for exceptions. See Design Guidelines for Exceptions.
This suggests that using Thread.Abort is an appropriate way to terminate a thread. Has something changed while I wasn't looking? The last I'd heard was this could cause unexpected behaviours so shouldn't be used.
Thread.Abort is a lot safer than it used to be for the following reasons.
The runtime will defer aborts while execution is in unmanaged code.
The abort will allow finally blocks to execute.
However, there is still a problem with exactly when the ThreadAbortException gets injected. Consider this code.
public class Example
{
private DateTime value = DateTime.MinValue;
public void DoSomething()
{
try
{
value = DateTime.UtcNow;
}
finally
{
}
}
}
If this code were running on a 32-bit platform the value variable could be corrupted if Thread.Abort was called and the ThreadAbortException were injected in the middle of the write to value. Since DateTime is 8 bytes the write has to take place using more than one instruction.
It is possible to guard against this by placing critical code in a finally block and by using Constrained Execution Regions, but it would be incredibly difficult to get right for all but the simplest types your define. And even then you cannot just put everything in a finally block.
Generally speaking, Thread.Abort will kill threads, leaving the data they were processing at the time in an unknown state. The state being unknown, it's usually not safe to deal with that data anymore. However, when you're trying to terminate a process, you are not expecting to deal with that thread's data anymore, so why not abort it?
Well, the problem with Thread.Abort() is that will abort the thread possibly in the middle of work. That might cause your state to be corrupted. That's why is advisable to use a volatile bool flag to control the thread, and let the thread finish its task gracefully, but based on that flag.
For more details, I recall this blog post.

What is the recommended way to guard against resource leaks in the context of ThreadAbortException?

I'm working on improving the exception-safety of a piece of code and I realized that a raised ThreadAbortException may cause undesired resource leaks, even when guarding resources with the C# using construct. For instance, consider the following code (which could be running in a separate thread).
using (TextWriter writer = CreateWriter(filename))
{
// do something with the writer.
}
TextWriter CreateWriter(string filename)
{
return new CustomWriter(File.OpenWrite(filename));
}
If the thread running this code is abnormally terminated, then I would like the file handle referenced by filename to be closed immediately. Can I do this without replacing the use of the using construct with a try/finally block?
My assumption is that ThreadAbortException may be raised at anytime, which means I should pay attention to what is happening between statements. While I can guard against the exception in CreateWriter with a try/finally block, the using construct won't do the same until after the expression in the parenthesis is evaluated, meaning the file resource is left open if the exception occurs immediately after CreateWriter returns.
I understand that a finalizer will ultimately release the file handle, but I am wondering if there is a deterministic way to address this issue without catching ThreadAbortException in each place that CreateWriter is used.
Yes, the deterministic way of preventing this is by not using Thread.Abort. Ever. Signal to your threads that is is time to stop, and let them terminate gracefully. Thread.Abort is a great big red-herring, placed in the API solely to trip you up. ;)
http://www.interact-sw.co.uk/iangblog/2004/11/12/cancellation
There is a tradeoff.
Be sure to close all resources immediately, even in the presence of ThreadAbortException
Have simpler code, but temporarily leak resources if Abort() is called
I assume that you are not calling Abort, and just want a way to be safe if someone else does. If you are calling Abort, then I'd advise that you don't. This isn't the only problem you will run into. There are other problems with Abort in the documentation.
#2 is a valid choice because callers of Abort() should expect this.
If you want to choose #1, then I don't think even a simple try/catch will help. If the ThreadAbortException can happen everywhere, then it can still happen after the file is opened (inside File.OpenWrite()) and before you can assign it to a variable that you can call Dispose() on -- you will have the same problem as using in your code.
You need semantics like
using (var handle = GetUnOpenedHandle()) {
handle.Open(); // this can't involve assignment to any field of handle
}
I'm not sure this is possible.
In many cases (but definitely not all) you could guard against a ThreadAbortException. Most of the critical code in the .NET BCL does this fairly well already. The problem is that it is really hard to get right. And for this reason most people recommend, and rightly so, to avoid aborting threads. Starting in version 2.0 the CLR made thread aborts a lot more tolerable and introduced a new set of APIs to help code authors guard against them. Take a look at Constrained Execution Regions for an in depth look at how all of this works.
I believe you are correct about your concerns with the example of the using block. For constrained execution regions to work correctly the out-of-band (asynchronous) exception must occur from within a try block. But, because of the way using expands out the expression is evaluated outside of the try block. Contrast that with the expansion of the lock block which evaluates the expression from within the try block. Well, that is true with version 4.0 of the framework anyway and that was changed specifically to guard against these exceptions.
So the question is why was the same change not made with the using block. According to Joe Duffy this was an acceptable omission because the assumption is that thread aborts should always be followed by a termination of the AppDomain which would fire off the finalizers anyway.
So yes. Your code is not tolerant of out-of-band (asynchronous) exceptions. But, the prevailing wisdom from those smarter than me is that it should not have to be.
A thread abort is most often used in the case of a fatal error, so your response should probably be to let your application terminate. If your trying to stop your own threads cleanly, use Thread.Join().

lock keyword in C#

I understand the main function of the lock key word from MSDN
lock Statement (C# Reference)
The lock keyword marks a statement
block as a critical section by
obtaining the mutual-exclusion lock
for a given object, executing a
statement, and then releasing the
lock.
When should the lock be used?
For instance it makes sense with multi-threaded applications because it protects the data. But is it necessary when the application does not spin off any other threads?
Is there performance issues with using lock?
I have just inherited an application that is using lock everywhere, and it is single threaded and I want to know should I leave them in, are they even necessary?
Please note this is more of a general knowledge question, the application speed is fine, I want to know if that is a good design pattern to follow in the future or should this be avoided unless absolutely needed.
When should the lock be used?
A lock should be used to protect shared resources in multithreaded code. Not for anything else.
But is it necessary when the application does not spin off any other threads?
Absolutely not. It's just a time waster. However do be sure that you're not implicitly using system threads. For example if you use asynchronous I/O you may receive callbacks from a random thread, not your original thread.
Is there performance issues with using lock?
Yes. They're not very big in a single-threaded application, but why make calls you don't need?
...if that is a good design pattern to follow in the future[?]
Locking everything willy-nilly is a terrible design pattern. If your code is cluttered with random locking and then you do decide to use a background thread for some work, you're likely to run into deadlocks. Sharing a resource between multiple threads requires careful design, and the more you can isolate the tricky part, the better.
All the answers here seem right: locks' usefulness is to block threads from acessing locked code concurrently. However, there are many subtleties in this field, one of which is that locked blocks of code are automatically marked as critical regions by the Common Language Runtime.
The effect of code being marked as critical is that, if the entire region cannot be entirely executed, the runtime may consider that your entire Application Domain is potentially jeopardized and, therefore, unload it from memory. To quote MSDN:
For example, consider a task that attempts to allocate memory while holding a lock. If the memory allocation fails, aborting the current task is not sufficient to ensure stability of the AppDomain, because there can be other tasks in the domain waiting for the same lock. If the current task is terminated, other tasks could be deadlocked.
Therefore, even though your application is single-threaded, this may be a hazard for you. Consider that one method in a locked block throws an exception that is eventually not handled within the block. Even if the exception is dealt as it bubbles up through the call stack, your critical region of code didn't finish normally. And who knows how the CLR will react?
For more info, read this article on the perils of Thread.Abort().
Bear in mind that there might be reasons why your application is not as single-threaded as you think. Async I/O in .NET may well call-back on a pool thread, for example, as do some of the various timer classes (not the Windows Forms Timer, though).
Generally speaking if your application is single threaded, you're not going to get much use out of the lock statement. Not knowing your application exactly, I don't know if they're useful or not - but I suspect not. Further, if you're application is using lock everywhere I don't know that I would feel all that confident about it working in a multi-threaded environment anyways - did the original developer actually know how to develop multi-threaded code, or did they just add lock statements everywhere in the vague hope that that would do the trick?
lock should be used around the code that modifies shared state, state that is modified by other threads concurrently, and those other treads must take the same lock.
A lock is actually a memory access serializer, the threads (that take the lock) will wait on the lock to enter until the current thread exits the lock, so memory access is serialized.
To answer you question lock is not needed in a single threaded application, and it does have performance side effects. because locks in C# are based on kernel sync objects and every lock you take creates a transition to kernel mode from user mode.
If you're interested in multithreading performance a good place to start is MSDN threading guidelines
You can have performance issues with locking variables, but normally, you'd construct your code to minimize the lengths of time that are spent inside a 'locked' block of code.
As far as removing the locks. It'll depend on what exactly the code is doing. Even though it's single threaded, if your object is implemented as a Singleton, it's possible that you'll have multiple clients using an instance of it (in memory, on a server) at the same time..
Yes, there will be some performance penalty when using lock but it is generally neglible enough to not matter.
Using locks (or any other mutual-exclusion statement or construct) is generally only needed in multi-threaded scenarios where multiple threads (either of your own making or from your caller) have the opportunity to interact with the object and change the underlying state or data maintained. For example, if you have a collection that can be accessed by multiple threads you don't want one thread changing the contents of that collection by removing an item while another thread is trying to read it.
Lock(token) is only used to mark one or more blocks of code that should not run simultaneously in multiple threads. If your application is single-threaded, it's protecting against a condition that can't exist.
And locking does invoke a performance hit, adding instructions to check for simultaneous access before code is executed. It should only be used where necessary.
See the question about 'Mutex' in C#. And then look at these two questions regarding use of the 'lock(Object)' statement specifically.
There is no point in having locks in the app if there is only one thread and yes, it is a performance hit although it does take a fair number of calls for that hit to stack up into something significant.

Categories

Resources