Im trying to hunt down a race condition, and I come across a lot of suspecious functions. Most of them are not allowed to be called from two threads at the same time, but its hard to make sure they don't.
Is there some keyword to instruct the runtime to throw an exception as soon as a function is executing in parallel? I know I sometimes get an exception when another thread modifies a collection which im enumerating, but are safeguards like that enough to rely on?
The runtime can halt execution using the lock instruction, so all I need is a lock which throws an error.
You can use Monitor.TryEnter for this:
bool entered = !Monitor.TryEnter(someLockObject);
try
{
if (!entered)
throw Exception("Multi-thread call!");
// Actual code
}
finally
{
if (entered)
{
Monitor.Exit(someLockObject);
}
}
And it would be good to wrap that code in its own class:
public sealed class MultiThreadProtector : IDisposable
{
private object syncRoot;
public MultiThreadProtector(object syncRoot)
{
this.syncRoot = syncRoot;
if (!Monitor.TryEnter(syncRoot))
{
throw new Exception("Failure!");
}
}
public void Dispose()
{
Monitor.Exit(this.syncRoot);
}
}
This way you can execute it as follows:
using (new MultiThreadProtector(someLockObject))
{
// protected code.
}
Related
I have an IDisposable object that can be accessed between multiple threads. I am trying to figure out a way to track that the object is "in use" before performing any clean up. In other words, I need to keep some sort of reference count to indicate that there are running methods (which are decremented when they complete) so that the Dispose method wouldn't continue until they are all complete (or after some timeout has passed). But I also need to make sure that once Dispose has been entered that any future calls to Method fail.
Something like:
class MyObject : IDisposable
{
private long _counter;
private bool _stopping;
private IDisposable _someResource;
public void Method()
{
if (_stopping)
throw new InvalidOperationException();
Interlocked.Increment(ref _counter);
try
{
// do some work
}
finally
{
Interlocked.Decrement(ref _counter);
}
}
public void Dispose()
{
var timeout = DateTime.Now.Add(TimeSpan.FromSeconds(15));
while ( DateTime.Now < timeout && Volatile.Read(ref _counter) > 0)
{
// wait
// Thread.Sleep(10) or something
}
_stopping = true;
//perform clean up
_someResource.Dispose();
}
}
However this won't work because Method() may be called again and _stopping hasn't been set but the Dispose would continue, invalidating everything else.
Is there a specific pattern that I can use here or perhaps some framework classes that can be used to solve this? Basically some two-way signal telling Dispose that nothing is in process so its good-to-go while signalling Method that it should fail.
I found CountdownEvent but I'm not sure how I can use it here. This answer shows an example CountdownLatch but it doesn't prevent new work from being requested.
No. Just say no to the Dispose method being responsible for "tracking" all instances consuming the class. The consumers of the class need to handle their clean-up and properly dispose.
If Dispose can be called multiple times by multiple classes, then you've just found a code smell. Only one class should being calling the dispose method; and that class should be tracking the consumers of the class with the Dispose method.
A common pattern for preventing dispose from being called multiple times is to set up a flag, similar to what you have now. Use the ObjectDisposedException as needed:
private bool _zombified;
public void Method()
{
if (_zombified)
throw new ObjectDisposedException();
// method's logic
}
public void Dispose
{
if(_zombified)
{
return;
}
_zombified = true;
// perform clean-up
}
In an application that I am developing I will be using 2 threads to do various operations. (I will not go into detail here.) These threads work in loops, checking if there is work to be done, doing work, calculating the time they need to wait and waiting. (See below)
public Global : System.Web.HttpApplication
{
private static Thread StartingDateThread;
private static Thread DeadlineDateThread;
private static object o1;
private static object o2;
public static Thread GetStartingDateThreadInstance
{
get
{
if(StartingDateThread==null)
{
StartingDateThread=new Thread(new ThreadStart(MonitorStartingDates));
}
return StartingDateThread;
}
}
public static Thread GetDeadlineThreadInstance
{
get
{
if(DeadlineDateThread==null)
{
DeadlineDateThread=new Thread(new ThreadStart(MonitorDeadlines));
}
return DeadlineDateThread;
}
}
public static object GetFirstObjectInstance
{
get
{
if(o1==null)
{
o1=new object();
}
return o1;
}
}
public static object GetSecondObjectInstance
{
get
{
if(o2==null)
{
o2=new object();
}
return o2;
}
}
protected void Application_Start(object sender, EventArgs e)
{
GetStartingDateThreadInstance.Start();
GetDeadlineThreadInstance.Start();
//////////////////////
////Do other stuff.
}
public void MonitorStartingDates()
{
while(true)
{
//Check if there is stuff to do.
//Do stuff if available.
//Check if there will be stuff to do in the future and if there is, check
//the time to wake up.
//If there is nothing to do, sleep for a pre-determined 12 hours.
if(StuffToDoInFuture)
{
Monitor.Enter(GetFirstObjectInstance);
Monitor.Wait(WaitingTime);
Monitor.Exit(GetFirstObjectInstance);
}
else
{
Monitor.Enter(GetFirstObjectInstance);
Monitor.Wait(new TimeSpan(12, 0, 0));
Monitor.Exit(GetFirstObjectInstance);
}
}
}
public void MonitorDeadlines()
{
while(true)
{
//Check if there is stuff to do.
//Do stuff if available.
//Check if there will be stuff to do in the future and if there is, check
//the time to wake up.
//If there is nothing to do, sleep for a pre-determined 3 days and 12 hours.
if(StuffToDoInFuture)
{
Monitor.Enter(GetSecondObjectInstance);
Monitor.Wait(WaitingTime);
Monitor.Exit(GetSecondObjectInstance);
}
else
{
Monitor.Enter(GetSecondObjectInstance);
Monitor.Wait(new TimeSpan(3, 12, 0, 0));
Monitor.Exit(GetSecondObjectInstance);
}
}
}
As you can see these two threads are started in the Application_Start method in the asax file. They operate if there is stuff available to do and then they calculate the time period they need to wait and then they wait. However, as users of the web application do operations new records will be inserted into the database and there will be circumstances where any of the two threads will have to resume operation sooner than planned. So, say I have a method in my DataAccess class which inserts into the database new data. (See below)
public class DataAccess
{
///////////////
//
public void InsertNewAuction()
{
///Insert new row calculate the time
Monitor.Pulse(Global.GetFirstObjectInstance);
Monitor.Pulse(Global.GetSecondObjectInstance);
///
}
}
It seems like this is an invalid operation, because at the stage where the Monitor.Pulse is called from the InsertNewAuction method I get an exception. Something like "Object synchronization method was called from an unsynchronized block of code." Is there any way of doing this? Thanks for your help
As to the specific error you're seeing, this is because Monitor.Pulse must be called inside the Monitor lock, like this (I've used lock rather than Enter/Exit, as it's safer for making sure the lock is always released, since it uses a proper try/finally block):
lock (Global.GetFirstObjectInstance)
{
Monitor.Pulse(Global.GetFirstObjectInstance);
}
In regard to the more general design question here, it's often dangerous to expose lock objects as public (or even worse, global) fields. In particular, it can be a recipe for deadlocks when multiple global locks are exposed and acquired in differing orders or when you have cases like blocking dispatches to the UI thread while holding a lock. Consider looking into alternate ways to accomplish what you're after.
As noted in the other answer, you have to acquire the lock before you can call Monitor.Pulse() on the monitor object.
That said, your code has at least one other serious bug: you are not initializing the synchronization object in a thread-safe way, which could easily lead to two different threads using two different object instances, resulting in no synchronization between those threads:
public static object GetFirstObjectInstance
{
get
{
if(o1==null)
{
o1=new object();
}
return o1;
}
}
If two threads call this getter simultaneously, they each may see o1 as null and try to initialize it. Then each might return a different value for the object instance.
You should simply initialize the object in a initializer:
private static readonly object o1 = new object();
And then return it from the getter:
public static object GetFirstObjectInstance { get { return o1; } }
That addresses the thread-safety issue. But you still have other issues with the code. First, you should encapsulate synchronization in an object, not expose the actual synchronization object instance. Second, assuming you are going to expose the synchronization object, I don't understand why you bother with the property, since you made the field public. The field should be private if you want to use a property as well.
It would also be better if the property followed normal .NET naming conventions. A method that returned the object would have "Get" in the name, but a property would not. Just name it "FirstObjectInstance".
Also as noted by Dan, use lock everywhere you want to acquire the lock.
There may be other issues in the code as well...I didn't do a thorough review. But the above you need to fix for sure.
I'm thinking about creating some classes along a "single-use" design pattern, defined by the following features:
Instances are used for performing some task.
An instance will execute the task only once. Trying to call the execute method twice will raise an exception.
Properties can be modified before the execute method is called. Calling them afterward will also raise an exception.
A minimalist implementation might look like:
public class Worker
{
private bool _executed = false;
private object _someProperty;
public object SomeProperty
{
get { return _someProperty; }
set
{
ThrowIfExecuted();
_someProperty = value;
}
}
public void Execute()
{
ThrowIfExecuted();
_executed = true;
// do work. . .
}
private void CheckNotExcecuted()
{
if(_executed) throw new InvalidOperationException();
}
}
Questions:
Is there a name for this?
Pattern or anti-pattern?
This looks like a form of a balking pattern.
If it appears logical for your specific object to behave in this way, I don't see a problem with it.
Streams behave in somewhat similar way (also their use Dispose/Close to lock them for most operations). So it is not exactly surprising pattern.
This question already has answers here:
how to obtain a lock in two places but release on one place?
(4 answers)
Closed 8 years ago.
I want to reask my previous question how to obtain a lock in two places but release on one place? because it seems too old and noone sees my updated code.
The question is - is my code correct and how to fix it if not?
I've tried similar code in the application and it hangs, but I don't now why, so I guess probably my code still wrong...
public void obtainLock() {
if (needCallMonitorExit == false) {
Monitor.Enter(lockObj);
needCallMonitorExit = true;
}
// doStuff
}
public void obtainReleaseLock() {
try {
lock (lockObj) {
// doAnotherStuff
}
} finally {
if (needCallMonitorExit == true) {
needCallMonitorExit = false;
Monitor.Exit(lockObj);
}
}
}
One of my methods should obtain the lock. another method should obtain the same lock and release it. sometimes just obtainReleaseLock is called. sometimes obtainLock is called (probably several times) and after a while obtainReleaseLock is called. These two methods are always called from the same thread, however lockObj is used in another thread for synchronization.
If you really need to go this way and don't want to use the alternatives provided by Marc, at least, put it into its own class:
public class LockObject
{
object _syncRoot = new object();
object _internalSyncRoot = new object();
public LockToken Lock()
{
lock(_internalSyncRoot)
{
if(!_hasLock)
{
Monitor.Enter(_syncRoot);
_hasLock = true;
}
return new LockToken(this);
}
}
public void Release()
{
lock(_internalSyncRoot)
{
if(!_hasLock)
return;
Monitor.Exit(_syncRoot);
_hasLock = false;
}
}
}
public class LockToken : IDisposable
{
LockObject _lockObject;
public LockToken(LockObject lockObject) { _lockObject = lockObject; }
public void Dispose() { _lockObject.Release(); }
}
This would allow you to use it like this:
LockObject _lockObj = new LockObject();
public void obtainLock()
{
_lockObj.Lock();
// doStuff
}
public void obtainReleaseLock()
{
using(_lockObj.Lock())
{
// doAnotherStuff
}
}
One word of caution:
If your thread is aborted after the call to obtainLock and before the call to obtainReleaseLock, your program will deadlock.
If you use Monitor.Enter you will need to call exactly that many Monitor.Exit calls on the same object, on the same thread. By using a lock block this is automatically done for you - as soon as you are outside the scope of the lock block, the lock count is decreased. Within the same thread it is perfectly legal to lock multiple times on the same object (via both mechanisms).
Keeping that in mind, maintaining your own "lock state" variable would only make things more complex. What if two threads access the needCallMonitorExit variable at the same time?
If I were you I would stick to lock blocks, and re-order code to fit inside them. Put as little code inside the blocks as possible.
I have a method in a class that performs several tasks (calling other methods, etc). The whole process can have along the way some errors or problems, but this doesn't mean that the process is aborted. I want that after the method finished, it returns to the caller a list of all of this problems so that he can decide what to do with them.
what's the best approach to implement this?
The first thing that comes to my mind is to make the method return a List of some kind of error class, but i may need to return something else with it, so that would be a problem. Also, throwing exceptions isn't good, because that would stop the flow, and i need to collect the errors along the way, not stop execution and go back to the caller.
I was also thinking of raising some kind of event that the caller listens to, but that would mean several events (for each error), and i just want that to happen once.
ideas?
My first idea is to create a class that would be an accumulator for these errors, e.g.
class ProcessingErrors
{
public void ReportError(...) { store the errror};
}
which you would pass in as a parameter:
MyResult DoProcessing(RealArgs a, ProcessingErrors e)
{
....
if(error) e.ReportError(...);
...
return result;
}
A few approaches
Your method will receive a delegate to an "error function" that will be called to report each error. The problem is that you need to pass this delegate around to all other methods.
Return a Tuple<RealResult, ErrorsList> so that the caller can examine both the result and the errors list.
If this is a repeated functionality and there are many methods that need to report errors - you can write a special class named, say, ErrorReportable and write LINQ operators that sequence objects of this type (if you know what a Monad is - then LINQ is just a simple monad and SelectMany is its "bind" operator). The code is cleaner but you need to do some work.
Create a delegate for errorcollecting along the way. Pass that to all classes in use, and let them report errors through this along the way. Let the calling class collect and handle the errors, or create a separate class for that. Something like below:
public delegate void ErrorCollector(string errorDescription);
public class MainControl
{
public void Execute()
{
new DoA(CollectErrors).DoStuff();
new DoB(CollectErrors).DoStuff();
//Display Errors encountered during processing in DoA and DoB
foreach (string s in _errorList)
{
Console.WriteLine(s);
}
}
public IList<string> ErrorList
{ get {return _errorList;} }
private void CollectErrors(string errorDescription)
{
_errorList.Add(errorDescription);
}
private readonly IList<string> _errorList = new List<string>();
}
public class DoA
{
private readonly ErrorCollector _errorCollector;
public DoA(ErrorCollector errorCollector)
{
_errorCollector = errorCollector;
}
public void DoStuff()
{
//Do something
//Perhaps error occurs:
_errorCollector("ERROR IN DoA!!!");
}
}
public class DoB
{
private readonly ErrorCollector _errorCollector;
public DoB(ErrorCollector errorCollector)
{
_errorCollector = errorCollector;
}
public void DoStuff()
{
//Do something
//Perhaps error occurs:
_errorCollector("ERROR IN DoB!!!");
}
}