I have following code:
private static readonly ReaderWriterLockSlim Locker = new ReaderWriterLockSlim();
private void TryGetReadLock()
{
if (!Locker.IsWriteLockHeld && !Locker.IsReadLockHeld)
Locker.TryEnterReadLock(WaitTimeout);
}
Locker.TryEnterReadLock times out. If I stop the debugger before it times out, both Locker.IsWriteLockHeld and Locker.IsReadLockHeld are false.
Question: why would TryEnterReadLock wait in this particular case?
[EDIT]
Indeed, as indicated in the comments I have lock between checking your if condition and entering the if block. So, I have tried to remove the if and leave just Locker.TryEnterReadLock(WaitTimeout);, but I receive the following error:
Additional information: A read lock may not be acquired with the write
lock held in this mode.
Indeed some other thread has a write lock (Locker.IsWriteLockHeld = true).
What I want is obtain classic lock locking when one thread has the write lock, that is have the threads wait until one it finishes, but I cannot find a way to do it.
Related
I have an application that runs a thread to play one or more songs. To create playlists, I update the information every second grid. After creating a playlist, if the thread is not started and the playlist is greater than 0, I run a thread to play songs.
This is the scan I do:
if(!thrPlayMusic.IsAlive && existData)
thrPlayMusic.Start();
However, on some occasions, the system is generating the exception ThreadStateException (), saying that the thread is already started. But how can he throw this exception, and check if the thread is active and then start its processing? can someone help me? Thank you!
You need to implement some kind of lock element. This will prevent multiple threads from accessing a piece of code and prevents race conditions like the one you describe.
Rework your code to something like
private static object lockObject = new lockObject();
With the above lock
lock(lockObject)
{
if(!thrPlayMusic.IsAlive && existData)
thrPlayMusic.Start();
}
This will ensure only one thread is in the lock block; any other threads coming in will wait on the lock statement until the current thread is done.
Note: The above will not work well if the thrPlayMusic.Start(); method takes a long time to return.
I have question regarding threading in c#.See the code posted below.
public class TestThreading
{
private System.Object lockThis = new System.Object();
public void Function1()
{
lock (lockThis)
{
// Access thread-sensitive resources.
}
}
public void Function2(){
lock (lockThis)
{
// Access thread-sensitive resources.
}
}
}
Now my question is if some thread entered in Function1 (inside lock block) and at the same time another thread enters in Function2 what will happen
The threads will execute independently.
The thread which entered in Function 2 Goes to waits until lock is released by Funtion1 thread.
The thread which entered in Function 2 throws exception.
I am new to c# hence asking simple basic question.
Thanks in advance.
The thread which entered in Function 2 Goes to waits until lock is released by Funtion1 thread.
The purpose of the lock is just that: provide a "safe" region of code that can be accessed only by one thread at a time. The other thread will be put to sleep, and resumed when the first one releases the lock.
Number 2 will happen. The second thread will wait for the lock to be released before executing.
The second thread will wait for the first one to release the lock and only then it will acquire the lock and preform your code
I suggest reading the following articles which describe MultiThreading issues and libraries
Managed Threading Best Practices
Threading in C#
Joseph Albahari
I have two working threads.I have locked both with a same lock, but threadB is getting executed before threadA, so exception came.I locked both using the same lock object.Thread B is using delegate function.How can I solve the issue.
Detailed Information:
I have a class called StateSimulation.
Inside that there are two functions called
a) OnSimulationCollisionReset
b) OnSimulationProgressEvent
Implementation is like this:
private void OnSimulationCollisionReset()
{
Thread XmlReset = new Thread(XmlResetFn);
XmlReset.Start();
}
private void OnSimulationProgressEvent()
{
DataStoreSingleTon.Instance.IsResetCompleted = true;
Thread ThrdSimulnProgress = new Thread(SimulnProgress);
ThrdSimulnProgress.Start();
}
where SimulnProgress() and XmlResetFn() are as follows:
private void SimulnProgress()
{
//uses a delegate
UIControlHandler.Instance.ShowSimulationProgress();
}
private void XmlResetFn()
{
DataStoreSingleTon.Instance.GetFPBConfigurationInstance().ResetXmlAfterCollision();
}
In which OnSimulationProgressEvent() is using a delegate function.
Both showSimulationProgress and ResetXML...() uses a same resource FPBArrayList.
My requirement is SimulationProgressEvent() should work only after Reset..(). In resetXML..() I clear the FPBList.
In SimulationProgress() I access FPBList[i] where i:0--->size;
I have locked both functions using a same lock object.I expected, reset() will complete first. But after entering to reset, before complete reset, showProgress() started and exception occured..
How to solve my issue?
This is how I locked the functions
public System.Object lockThis = new System.Object();
private void SimulnProgress()
{
lock (lockThis)
{
UIControlHandler.Instance.ShowSimulationProgress();
}
}
private void XmlResetFn()
{
lock (lockThis)
{
DataStoreSingleTon.Instance.GetFPBConfigurationInstance().ResetXmlAfterCollision();
}
}
Please give a solution.
Regards
Nidhin KR
It's not a good idea to write multithreaded code that assumes or requires that execution on different threads occurs in a particular order. The whole point of multithreading is to allow things to be executed independently of each other. Independently means no particular order is expressed or implied. CPU time might not be distributed evenly between the two threads, for example, particularly is one thread is waiting for an external signaling event and the other thread is in a compute loop.
For your particular code, it seems very odd that IsResetCompleted = true; is set in the OnSimulationProgressEvent handler. The completion state of the Reset activity should be set by the Reset activity, not by some other event executing in another thread assuming "If we're here, the work in the other thread must be finished."
You should review your design and identify your assumptions and dependencies between threads. If thread B must not proceed until after thread A has completed something, you should first reexamine why you're putting this work in different threads, and then perhaps use a synchronization object (such as an AutoResetEvent) to coordinate between the threads.
The key point here is if you take a sequential task and split it into multiple threads, but the threads use locks or synch objects to serialize their execution, then there is no benefit to using multiple threads. The operation is still sequential.
Locks are intended to prevent several threads from entering a given section of code simultaneously. They are not intended to synchronize the threads in any other way, like, making them execute code in some specific order.
To enforce the execution order you need to implement some signalling between your threads.
Have a look at Synchronization Primitives, specifically, Auto/ManualResetEvent is probably what you want.
I am not sure if I understand the question entirely, but if your requirement is simply that you want to prevent the body of SimulnProgress from executing before XmlResetfn has executed at least once, you can do:
public readonly object lockThis = new object();
private readonly ManualResetEvent resetHandle = new ManualResetEvent(false);
private void SimulnProgress()
{
resetHandle.WaitOne();
lock (lockThis)
{
UIControlHandler.Instance.ShowSimulationProgress();
}
}
private void XmlResetFn()
{
lock (lockThis)
{
DataStoreSingleTon.Instance.GetFPBConfigurationInstance().ResetXmlAfterCollision();
}
resetHandle.Set();
}
In my application I have a form that starts synchronization process and for number of reasons I want to allow only one synchronization to run at a time. So I've added a static bool field to my form indicating whether sync is in progress and added a lock to set this field to true if it wasn't already set so that first thread could start synchronization but when it's running every other thread that will try to start it will terminate.
My code is something like this:
internal partial class SynchronizationForm : Form
{
private static volatile bool workInProgress;
private void SynchronizationForm_Shown(object sender, EventArgs e)
{
lock (typeof(SynchronizationForm))
{
if (!workInProgress)
{
workInProgress = true;
}
else
{
this.Close();
}
}
}
}
This is working well but when I run Code Analysis on my project I'm getting the following warning message:
CA2002 : Microsoft.Reliability : 'SynchronizationForm.SynchronizationForm_Shown(object, EventArgs)' locks on a reference of type 'Type'. Replace this with a lock against an object with strong-identity.
Can anyone explain to me what's wrong with my code and how can I improve it to make the warning gone. What does it mean that object has a strong-identity?
What is wrong is that you are locking on something public (typeof(SynchronizationForm)) which is accessible everywhere from your code and if some other thread locks on this same thing you get a deadlock. In general it is a good idea to lock only on private static objects:
private static object _syncRoot = new object();
...
lock (_syncRoot)
{
}
This guarantees you that it's only SynchronizationForm that could possess the lock.
From the MSDN explanation of the rule
An object is said to have a weak identity when it can be directly accessed across application domain boundaries. A thread that tries to acquire a lock on an object that has a weak identity can be blocked by a second thread in a different application domain that has a lock on the same object.
Since you can't necessarily predict what locks another AppDomain might take, and since such locks might need to be marshalled and would then be expensive, this rule makes sense to me.
The problem is that typeof(SynchronizationForm) is not a private lock object, which means that any other piece of code could use it to lock on, which could result in deadlock. For example if some other code did this:
var form = new SynchronizationForm();
lock(typeof(SynchronizationForm))
{
form.SomeMethodThatCausesSynchronizationForm_ShownToBeCalled();
}
Then deadlock will occur. Instead you should delcare a private lock object in the SynchronizationForm class and lock on that instead.
The System.Type object of a class can conveniently be used as the mutual-exclusion lock for static methods of the class.
Source: http://msdn.microsoft.com/en-us/library/aa664735(VS.71).aspx
To add to Doug's answer, what you have here is a locking mechanism which should only be used in static methods, being used in an instance method.
I have a situation where I might have multiple instances of a program running at once, and it's important that just one specific function not be executing in more than one of these instances at once.
Is this the proper way to use a mutex to prevent this from happening?
lock (this.GetType()) {
_log.Info("Doing Sync");
DoSync();
_log.Info("Sync Completed");
}
You said multiple instances of one application, so we're talking about two program.exe's running, right? The lock statement won't lock across multiple programs, just within the program. If you want a true Mutex, look at the System.Threading.Mutex object.
Here is a usage example:
bool createdNew;
using (Mutex mtx = new Mutex(false, "MyAwesomeMutex", out createdNew))
{
try
{
mtx.WaitOne();
MessageBox.Show("Click OK to release the mutex.");
}
finally
{
mtx.ReleaseMutex();
}
}
The createdNew variable will let you know whether or not it was created the first time. It only tells you if it has been created, though. If you want to acquire the lock, you need to call WaitOne and then call ReleaseMutex to release it. If you just want to see if you created a Mutex, just constructing it is fine.
TheSeeker is correct.
Jeff Richter's advice in Clr Via C# (p638-9) on locking is to create a private object specifically for the purpose of being locked.
private Object _lock = new Object();
// usage
lock( _lock )
{
// thread-safe code here..
}
This works because _lock cannot be locked by anything outside the current class.
EDIT: this is applicable to threads executing within a single process. #David Mohundro's answer is correct for inter-process locking.