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();
}
Related
I have a code which synchronize threads via AutoResetEvent
Basically there are two threads which swap control and execute commands , each thread at a time.
Code :
static EventWaitHandle _waitHandle = new AutoResetEvent(false);
static void Waiter()
{
_waitHandle.WaitOne();
Console.WriteLine("A...");
_waitHandle.Set();
_waitHandle.WaitOne();
Console.WriteLine("A2...");
_waitHandle.Set();
}
static void Waiter2()
{
_waitHandle.WaitOne();
Console.WriteLine("B...");
_waitHandle.Set();
_waitHandle.WaitOne();
Console.WriteLine("B2...");
}
void Main()
{
new Thread(Waiter).Start();
new Thread(Waiter2).Start();
_waitHandle.Set(); // Wake up the Waiter.
}
Result : (I always get this result)
A...
B...
A2...
B2...
However - when I move to Tasks :
Task.Run(()=>Waiter());
Task.Run(()=>Waiter2());
I sometimes get :
B...
A...
B2...
Which is clear to me because the task scheduler scheduled the second task to execute first.
Which leads me to ask :
Questions
1) Do threads order guaranteed to be the same as order of invocation in :
new Thread(Waiter).Start();
new Thread(Waiter2).Start();
//In other words , will I always get the first result ?
2) How can I Force the Task.Runs to be invoked the same order as I invoke them?
No, it is not guaranteed, you just got lucky that the output was the same every time.
Add in a 2nd AutoResetEvent that has a WaitOne between the two tasks and a Set in at the start of the Waiter method.
Without a synchronization mechanism, you cannot guarantee the order in which a thread will start and/or execute. Furthermore, a thread's execution may be preempted (think: "paused") at any time.
So to answer your questions:
No
No
Before moving forward, you should ask yourself "Do I really need to use threads to solve this problem?"
My favorite quote from the Microsoft's MSDN:
"When you use multithreading of any sort, you potentially expose yourself to very serious and complex bugs" [Best Practices for Implementing the Event-based Asynchronous Pattern]
If you do need to introduce threads, then I would begin by familiarizing yourself with some of Microsoft's synchronization mechanisms:
Critical Section
Mutex
Events
Auto Reset
Manual Reset
In my application I use a ReaderWriterLockSlim to synchronize reads and writes from/to a list<>.
In the following example reading the list is performed inside all 3 sub-methods, thus these 3 should be packed into a ReadLock. The problem is that SubMethod3 is called via a BackgroundWorker (as it contains lengthy calculations), so the ExitReadLock() in the finally block of MainMethod1 might be called before SubMethod3 has been finished by the BackgroundWorker (separate thread). Thereby the code in SubMethod3 is not really protected by the lock.
What I have considered is to use a lock in each sub-method, so Submethod3 would have its own lock, which would be released when the BackgroundWorker was done. The problem with this approach is that another thread could enter in between the calls of the sub-methods, as each of these would release the lock when done.
My question is: How can ReadLock be used to protect over more threads?
ReaderWriterLockSlim synchronizationLock = new ReaderWriterLockSlim();
public void MainMethod1()
{
synchronizationLock.EnterReadLock();
try
{
SubMethod1(); //Run on UI thread
SubMethod2(); //Run on UI thread
myBackgroundWorker.RunWorkerAsync();
}
finally
{
synchronizationLock.ExitReadLock();
}
}
private void myBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
SubMethod3(); //Run on separate thread
}
In general you are out of luck. Due to thread affinity, you cannot release the lock from another thread. If you try to hold the reader lock (with the idea that this will allow the worker to acquire its own read lock), and wait the worker thread to start, acquire a reader lock and notify you, so you can release the read lock at that time, all you'll get would be a deadlock if there is a waiting writer thread due to reader/waiter fairness of the ReaderWriterLock(Slim) implementation.
I see the following options:
(A) Run the whole MainMethod1 on a separate thread.
(B) Write and use your own reader/writer lock implementation that supports such scenario.
(C) Get rid of BackgroundWorker and switch to async/await implementation using one of the AsyncReaderWriterLock implementations described here ReaderWriterLockSlim and async\await
(D) Since I've noticed the comment Run on UI thread, only and only if the method is used by a thread that supports marshalling calls from another thread (which is true for WF and WPF UI threads), you can use the following technique:
public void MainMethod1()
{
synchronizationLock.EnterReadLock();
bool releaseLock = true;
try
{
SubMethod1();
SubMethod2();
RunWorkerCompletedEventHandler onRunWorkerCompleted = null;
onRunWorkerCompleted = (sender, e) =>
{
((BackgroundWorker)sender).RunWorkerCompleted -= onRunWorkerCompleted;
synchronizationLock.ExitReadLock();
};
myBackgroundWorker.RunWorkerCompleted += onRunWorkerCompleted;
myBackgroundWorker.RunWorkerAsync();
releaseLock = false;
}
finally
{
if (releaseLock)
synchronizationLock.ExitReadLock();
}
}
Please note than while option (D) seems to solve the issue in the context of MainMethod1, it can easily lead to a deadlock if the UI thread tries to acquire read lock from another place and there is a pending writer waiting.
In general working with long time hold locks from the UI thread is a bad idea that is causing more problems rather than solving something. IMO the best are the options (A) and (C), and so far (A) is the simplest if you can afford it (if SubMethod1 and SubMethod2 do not need to be run on the UI thread or can marshall the necessary calls to it).
Using C# to create a windows service application. I have a main object that creates worker threads to periodically conduct various tasks. Each worker completes a specific task, waits for a time, then repeats.
If one of those tasks should fail, I want that thread to alert the main to log that a task failed and then to exit.
I had thought about using a ManualResetEvent where Set would be called from each worker (and main would loop on checking it). Problem is, multiple workers could fail simultaneously and attempt to Set() the event at the same time.
Is there a thread-safe way to handle alerting from multiple worker threads? Only one alert is required, I don't need to handle any more than the first one received.
Why don't use Double-checked locking in your Setter / Event handler?
private static readonly object Locker = new object();
private bool _closing = false;
private void YourErrorHandler(object sender, EventArgs args)
{
if(!_closing)
lock (Locker)
if(!_closing)
{
_closing = true;
//What ever you need to do here
}
}
If you need cross process sync, you will need to use Mutex or something else. But hope you get the idea
Once one of the threads fails, you want to shut down the whole thing, correct? Once that happens, when you join all of the threads, you can check their status and report an error for each individual one that failed. Something like:
while(eventNotSet) sleep();
foreach(thread)
{
thread.Join();
checkStatus(thread);
}
I can have a maximum of 5 threads running simultaneous at any one time which makes use of 5 separate hardware to speedup the computation of some complex calculations and return the result. The API (contains only one method) for each of this hardware is not thread safe and can only run on a single thread at any point in time. Once the computation is completed, the same thread can be re-used to start another computation on either the same or a different hardware depending on availability. Each computation is stand alone and does not depend on the results of the other computation. Hence, up to 5 threads may complete its execution in any order.
What is the most efficient C# (using .Net Framework 2.0) coding solution for keeping track of which hardware is free/available and assigning a thread to the appropriate hardware API for performing the computation? Note that other than the limitation of 5 concurrently running threads, I do not have any control over when or how the threads are fired.
Please correct me if I am wrong but a lock free solution is preferred as I believe it will result in increased efficiency and a more scalable solution.
Also note that this is not homework although it may sound like it...
.NET provides a thread pool that you can use. System.Threading.ThreadPool.QueueUserWorkItem() tells a thread in the pool to do some work for you.
Were I designing this, I'd not focus on mapping threads to your HW resources. Instead I'd expose a lockable object for each HW resource - this can simply be an array or queue of 5 Objects. Then for each bit of computation you have, call QueueUserWorkItem(). Inside the method you pass to QUWI, find the next available lockable object and lock it (aka, dequeue it). Use the HW resource, then re-enqueue the object, exit the QUWI method.
It won't matter how many times you call QUWI; there can be at most 5 locks held, each lock guards access to one instance of your special hardware device.
The doc page for Monitor.Enter() shows how to create a safe (blocking) Queue that can be accessed by multiple workers. In .NET 4.0, you would use the builtin BlockingCollection - it's the same thing.
That's basically what you want. Except don't call Thread.Create(). Use the thread pool.
cite: Advantage of using Thread.Start vs QueueUserWorkItem
// assume the SafeQueue class from the cited doc page.
SafeQueue<SpecialHardware> q = new SafeQueue<SpecialHardware>()
// set up the queue with objects protecting the 5 magic stones
private void Setup()
{
for (int i=0; i< 5; i++)
{
q.Enqueue(GetInstanceOfSpecialHardware(i));
}
}
// something like this gets called many times, by QueueUserWorkItem()
public void DoWork(WorkDescription d)
{
d.DoPrepWork();
// gain access to one of the special hardware devices
SpecialHardware shw = q.Dequeue();
try
{
shw.DoTheMagicThing();
}
finally
{
// ensure no matter what happens the HW device is released
q.Enqueue(shw);
// at this point another worker can use it.
}
d.DoFollowupWork();
}
A lock free solution is only beneficial if the computation time is very small.
I would create a facade for each hardware thread where jobs are enqueued and a callback is invoked each time a job finishes.
Something like:
public class Job
{
public string JobInfo {get;set;}
public Action<Job> Callback {get;set;}
}
public class MyHardwareService
{
Queue<Job> _jobs = new Queue<Job>();
Thread _hardwareThread;
ManualResetEvent _event = new ManualResetEvent(false);
public MyHardwareService()
{
_hardwareThread = new Thread(WorkerFunc);
}
public void Enqueue(Job job)
{
lock (_jobs)
_jobs.Enqueue(job);
_event.Set();
}
public void WorkerFunc()
{
while(true)
{
_event.Wait(Timeout.Infinite);
Job currentJob;
lock (_queue)
{
currentJob = jobs.Dequeue();
}
//invoke hardware here.
//trigger callback in a Thread Pool thread to be able
// to continue with the next job ASAP
ThreadPool.QueueUserWorkItem(() => job.Callback(job));
if (_queue.Count == 0)
_event.Reset();
}
}
}
Sounds like you need a thread pool with 5 threads where each one relinquishes the HW once it's done and adds it back to some queue. Would that work? If so, .Net makes thread pools very easy.
Sounds a lot like the Sleeping barber problem. I believe the standard solution to that is to use semaphores
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.