Locking error in c# - c#

I am trying to do a request-response communication module in c#, using a SerialPort. The
This is a very simple implementation, just to demonstrate that it kinda-works (SerialPort is not working properly (it is a USB virtual COM port), and sometimes eats a few characters, probably some windows driver bug).
However the demo does not work :-/
When Using a propertygrid on the form, which reads out properties of an object, which in turn sends a request to read a property from the remote device, something very strange happens: More than one simulteneous call to SendCommand is made at once.
I tried using a lock{} block to make the calls sequenctial, but it does not work. Even with the lock, more than one call is enters the protected area.
Can you please tell me what am I doing wrong?
My code:
SerialPort sp;
public byte[] SendCommand(byte[] command)
{
//System.Threading.Thread.Sleep(100);
lock (sp)
{
Console.Out.WriteLine("ENTER");
try
{
string base64 = Convert.ToBase64String(command);
string request = String.Format("{0}{1}\r", target_UID, base64);
Console.Out.Write("Sending request... {0}", request);
sp.Write(request);
string response;
do
{
response = sp.ReadLine();
} while (response.Contains("QQ=="));
Console.Out.Write("Response is: {0}", response);
return Convert.FromBase64String(response.Substring(target_UID.Length));
}
catch (Exception e)
{
Console.WriteLine("ERROR!");
throw e;
}
finally
{
Console.Out.WriteLine("EXIT");
}
}
}
The output:
ENTER
Sending request... C02UgAABAA=
Response is: cgAABAAARwAAAA==
EXIT
ENTER
Sending request... C02UgQARwA=
ENTER
Sending request... C02UgAABAA=
Response is: gQARwAAPHhtbD48bWVzc2FnZT5IZWxsbyBYWDIhPC9tZXNzYWdlPjxkZXN0aW5haXRvbj5NaXNpPC9kZXN0aW5hdGlvbj48L3htbD4=
Notice the two ENTER-s, without an EXIT between them? How is that possible?

You need to keep in mind what the lock keyword does, it allows only one thread to enter the lock. Problem is, you are not using any threads. All of this code runs on the UI thread, the main thread of your program.
The next detail you need to know is that the UI thread is special, it is re-entrant. The sp.ReadLine(); call is going to block the UI thread. That is illegal, the UI thread of a GUI program operates as a "single threaded apartment", enabled by the [STAThread] attribute on your program's Main() method. The contract of an STA thread forbids it from blocking, that's very likely to cause deadlock.
To follow the requirements of an STA, the CLR does something special whenever code that runs on the UI thread performs a blocking operation, like SerialPort.ReadLine() does. It pumps a message loop to ensure that messages that Windows sends keep getting dispatched. That message loop does the same thing that Application.Run() does.
Maybe you can see where this is heading, the PropertyGrid is allowed to again call your SendCommand() method. The lock doesn't work at all, this happens on the same thread.
Solving this problem isn't so easy, we can't see the code that gets SendMessage() triggered. But you will need to prevent this from happening, somehow. More background on this behavior in this question.

Where is the field sp assigned? Locks only work on non-null objects.
If sp is assigned differently on each call, then the lock won't be mutually exclusive (locks are only mutually exclusive on the same object instance). In that case, you'd need to have a static field to be used for locking:
private static readonly object _lockObject = new object();
Edit: I see now based on comments in other answers that you are actually running this logic on the UI thread, which is causing the lock to be re-entered multiple times on the same thread (the UI thread) when the message queue is pumped. Run this code on a different thread, and you will gain two advantages: (1) the UI will not lock up as this potentially long-running code executes, and (2) the lock will always be acquired on a new thread, ensuring that subsequent calls to SendCommand will all be on their own thread, and thus enter the lock sequentially as desired.

There are two things you should try/change:
1.Make a separate field, that will be used for locking only
2.Apply the double lock check : double check locking

SerialPort sp;
public byte[] SendCommand(byte[] command)
{
//System.Threading.Thread.Sleep(100);
lock (sp)
{
Console.Out.WriteLine("ENTER");
try
{
string base64 = Convert.ToBase64String(command);
string request = String.Format("{0}{1}\r", target_UID, base64);
Console.Out.Write("Sending request... {0}", request);
sp.Write(request);
string response;
do
{
response = sp.ReadLine();
} while (response.Contains("QQ=="));
Console.Out.Write("Response is: {0}", response);
return Convert.FromBase64String(response.Substring(target_UID.Length));
}
catch (Exception e)
{
Console.WriteLine("ERROR!");
throw e;
}
finally
{
Console.Out.WriteLine("EXIT");
}
}
}

Related

c# catch an exception from delegate.begininvoke without calling delegate.endinvoke

I have a program that monitor a DB (or a number of DBs).
for this, I built a class that holds all the information about how to monitor the DB.
the class contains a delegate that points to a function that monitor the DB and changes the state field accordingly.
the main thread create a new instance of the class and calling the class.delegate.begininvoke().
the main thread checks the state of each created class in a loop and inform the user if any changes occur.
a simple example of the code:
Class Monitor
{
private Object lockObj;
private delegate void MonitorHandlerDelegate();
private MonitorHandlerDelegate mainHandler;
private int State;
private int DBid;
public Monitor(int DBid)
{
this.DBid = DBid;
mainHandler += MonitorHandler;
lockObj = new Object();
}
private void MonitorHandler()
{
do
{
state = CheckDB(DBid); // 0 is ok, 1 is fail, 2 is InWork, 3 is stop monitoring
} while (state != 3);
}
public int state
{
get { lock(lockObj) { return State;} }
set { lock(lockObj) {State = value;} }
}
public void Start()
{
this.state = 0;
this.mainHandler.BeginInvoke(null, null);
}
}
public Main()
{
Monitor firstMonitor = new Monitor(20);
firstMonitor.Start();
do
{
if(firstMonitor.state == 1) WriteLine("DB 20 stop working");
} while(true);
}
The problem I encountered is with exception handaling, if the MonitorHandler function throw an exception, i dont have a way to know it.
I dont call the EndInvoke so the exception is not re-throwing to the Main Thread.
My goal is to check the DB status by simply chack the state field of the monitor instance.
If an exception in throwen i need to somehow "transfer" this exception to the Main Thread but i dont want to start checking the state and the Monitor delegate status as well.
I whold love to find a way to the Monitor Thread itself (the one that activated by the .BeginInvoke), to throw the exception in the Main Thread.
Thank you.
I whold love to find a way to the Monitor Thread itself (the one that activated by the .BeginInvoke), to throw the exception in the Main Thread.
Other than something like ThreadAbortException, there is no mechanism to inject an exception into another arbitrary thread.
If you are going to use the delegate's BeginInvoke() method, and you want to catch the exception in a thread different from where the delegate itself is being invoked, then you will need to call EndInvoke() in that thread.
Your other option would be to deal with the exception explicitly and manually. I.e. catch the exception with try/catch in the worker thread, and then use an explicitly defined mechanism of your own choosing (e.g. a ConcurrentQueue<T>) to pass the caught exception to code running in the main thread.
All that said, using a delegate's BeginInvoke() method was never really that ideal a way to execute code asynchronously like that, and today it is even worse of an idea. It's not clear from your question what the nature of the "main thread" is, never mind whether that thread has a synchronization context. But assuming it does (e.g. it's a GUI thread, or an ASP.NET context, etc.) then your desired behavior is easily implemented using Task.Run() to start the asynchronous operation, and then using await in the main thread to capture the completion of that operation, along with any exception that is thrown.
For that matter, even if your main thread does not currently have a synchronization context, it might be the right approach is to give it one. Either by leveraging one of the existing mechanisms, or writing your own. This would be a good idea if, for example, you expect to run into this sort of "propagate the exception from the worker to the main thread" scenario in the code frequently. This would allow you to use the built-in language support for dealing with that (i.e. async/await), rather than having to kludge something for each instance. Implementing the synchronization context isn't trivial, but it's work you can do once, and then reuse over and over.

call method from another thread without blocking the thread (or write custom SynchronizationContext for non-UI thread) C#

This is probably one of the most frequent questions in the Stackoverflow, however I couldn't find the exact answer to my question:
I would like to design a pattern, which allows to start thread B from thread A and under specific condition (for example when exception occurs) call the method in thread A. In case of exception the correct thread matters a lot because the exception must call a catch method in the main thread A. If a thread A is an UI thread then everything is simple (call .Invoke() or .BeginInvoke() and that's it). The UI thread has some mechanism how it is done and I would like to get some insights how it would be possible to write my own mechanism for the non-UI thread. The commonly suggested method to achieve this is using the message pumping http://www.codeproject.com/Articles/32113/Understanding-SynchronizationContext-Part-II
but the while loop would block the thread A and this is not what I need and not the way how UI thread handles this issue. There are multiple ways to work around this issue but I would like to get a deeper understanding of the issue and write my own generic utility independently of the chosen methods like using System.Threading.Thread or System.Threading.Tasks.Task or BackgroundWorker or anything else and independently if there is a UI thread or not (e.g. Console application).
Below is the example code, which I try to use for testing the catching of the exception (which clearly indicates the wrong thread an exception is thrown to). I will use it as an utility with all the locking features, checking if a thread is running, etc. that is why I create an instance of a class.
class Program
{
static void Main(string[] args)
{
CustomThreads t = new CustomThreads();
try
{
// finally is called after the first action
t.RunCustomTask(ForceException, ThrowException); // Runs the ForceException and in a catch calls the ThrowException
// finally is never reached due to the unhandled Exception
t.RunCustomThread(ForceException, ThrowException);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
// well, this is a lie but it is just an indication that thread B was called
Console.WriteLine("DONE, press any key");
Console.ReadKey();
}
private static void ThrowException(Exception ex)
{
throw new Exception(ex.Message, ex);
}
static void ForceException()
{
throw new Exception("Exception thrown");
}
}
public class CustomThreads
{
public void RunCustomTask(Action action, Action<Exception> action_on_exception)
{
Task.Factory.StartNew(() => PerformAction(action, action_on_exception));
}
public void RunCustomThread(Action action, Action<Exception> action_on_exception)
{
new Thread(() => PerformAction(action, action_on_exception)).Start();
}
private void PerformAction(Action action, Action<Exception> action_on_exception)
{
try
{
action();
}
catch (Exception ex)
{
action_on_exception.Invoke(ex);
}
finally
{
Console.WriteLine("Finally is called");
}
}
}
One more interesting feature that I've found is that new Thread() throws unhandled Exception and finally is never called whereas new Task() does not, and finally is called. Maybe someone could comment on the reason of this difference.
and not the way how UI thread handles this issue
That is not accurate, it is exactly how a UI thread handles it. The message loop is the general solution to the producer-consumer problem. Where in a typical Windows program, the operating system as well as other processes produce messages and the one-and-only UI thread consumes.
This pattern is required to deal with code that is fundamentally thread-unsafe. And there always is a lot of unsafe code around, the more convoluted it gets the lower the odds that it can be made thread-safe. Something you can see in .NET, there are very few classes that are thread-safe by design. Something as simple is a List<> is not thread-safe and it up to you to use the lock keyword to keep it safe. GUI code is drastically non-safe and no amount of locking is going to make it safe.
Not just because it is hard to figure out where to put the lock statement, there is a bunch of code involved that you did not write. Like message hooks, UI automation, programs that put objects on the clipboard that you paste, drag and drop, shell extensions that run when you use a shell dialog like OpenFileDialog. All of that code is thread-unsafe, primarily because its author did not have to make it thread-safe. If you trip a threading bug in such code then you do not have a phone number to call and a completely unsolvable problem.
Making a method call run on a specific thread requires this kind of help. It is not possible to arbitrarily interrupt the thread from whatever it is doing and force it to call a method. That causes horrible and completely undebuggable re-entrancy problems. Like the kind of problems caused by DoEvents(), but multiplied by a thousand. When code enters the dispatcher loop then it is implicitly "idle" and not busy executing its own code. So can take an execution request from the message queue. This can still go wrong, you'll shoot your leg off when you pump when you are not idle. Which is why DoEvents() is so dangerous.
So no shortcuts here, you really do need to deal with that while() loop. That it is possible to do so is something you have pretty solid proof for, the UI thread does it pretty well. Consider creating your own.

What is the difference between these two methods for pausing/resuming threads?

I have a multithreaded application which is used to extract data from a website. I wanted to be able to pause and resume multiple threads from the UI. After searching on the web I came to know about two approaches that I can use to control (pause/resume) my threads.
Using Monitor class.
Using EventWaitHandle and ManualResetEvent class.
What I did:
I have a function named GetHtml that simply returns the html of the website. I am just showing the fraction part of this function for brevity.
public string GetHtml(string url, bool isProxy = false)
{
string result = "";
ExecutionGateway();
//->> EXTRA CODE FOR FETCHING HTML
return result;
}
I have a function ControlTasks used to control threads from UI, below I have explained the ControlTasks function using both thread control approaches using the Monitor class as well as the EventWaitHandle class (I will also briefly explain the working of the function ExecutionGateway).
1. Using the Monitor class
private object taskStopper = new object();
public bool ControlTasks(bool isPause)
{
try
{
if (isPause)
{
Monitor.Enter(taskStopper);
}
else
{
Monitor.Exit(taskStopper);
}
return true;
}
catch (Exception ex)
{
Logger.Instance.WriteLog("ControlTasks:", ex, Logger.LogTypes.Error);
return false;
}
}
ControlTasks is called from the UI where if isPause is true the exclusive lock is used on object taskStopper else releases the lock, Now here comes the function ExecutionGateway which is used to acquire lock on object taskStopper but it does nothing as the code below shows.
private void ExecutionGateway()
{
lock(taskStopper){ }
}
In this way all running threads enters waiting state when isPause is true in ControlTasks as taskStopper is exclusively locked and if isPause is false all threads resumes their processing.
2. Using the EventWaitHandle class
private EventWaitHandle handle = new ManualResetEvent(true);
public bool ControlTasks(bool isPause)
{
try
{
if (isPause)
{
handle.Reset();
}
else
{
handle.Set();
}
return true;
}
catch (Exception ex)
{
Logger.Instance.WriteLog("ControlTasks:", ex, Logger.LogTypes.Error);
return false;
}
}
This code also fundamentally does the same job, where the event state is signaled/non-signaled depending on the isPause parameter. Now, the corresponding ExecutionGateway method.
private void ExecutionGateway()
{
handle.WaitOne(Timeout.Infinite);
}
Problem:
What is the difference between these two approaches, is one better than the other? Are there any other ways to do this?
The main problem I have faced many times is if I use either of the above methods and I have 100 threads; when I pause them, then resume them after 5 or more minutes, the UI starts hanging. The UI is terrifically unresponsive. It gets updated but keeps on hanging and I keep getting the message "Not Responding" at each interval. One thing I want to mention each thread extracts data and notifies the UI about the data fetched through event handling. What could be the reason of this unresponsiveness? Is it a problem with my approach(es)?
I think it's always desirable to use a construct that communicates your intent clearly. You want a signal to other threads that they should wait (i.e. stop doing what they're doing) until you signal to them that they can start again. You have one controlling thread (your UI) and potentially many threads doing work and marshalling results back to the UI.
Approach 1 isn't ideal because locks (at least in my experience) are most often used to protect a resource that isn't suitable for use in multi threaded code. For example, writing to a shared field.
Approach 2 makes much more sense, a manual reset event functions like a gate: open the gate and things can pass through, close it and they can't. That's exactly the behaviour you're looking for and I think most developers would understand quite quickly that that's your intent.
As for your second problem, it sounds like you're getting waves of messages clogging the UI. If you stop all 100 of your threads then start them at the same time, there's a good chance they're going to finish their work quite close together and all be trying to send the result of their work to the UI thread. To solve that you could try staggering the work when you restart or use fewer threads. Another option would be to aggregate results and only dispatch the the UI every x seconds - but that's a bit more work.
In Option 1, using the Monitor class means that only one thread owns the exclusive lock of the monitor object at a time. This means that of your 100 threads, only 1 is processing at a time, which kind of defeats the purpose of using threads. It also means that your GUI thread has to wait until the current worker thread has finished before it can obtain the lock.
The ManualResetEvent is a much better choice as it is used to signal between threads, rather than protect against multiple thread access.
I do not know why your GUI is so unresponsive using the second option, but I do not think it is related to your manual reset event. More likely you have a different problem where the GUI thread is getting swamped. You suggest you have 100 threads all firing notification events to the GUI which would seem a likely culprit.
What happens if you debug your app, and just randomly break when your GUI is unresponsive? Doing this many times should show what your GUI thread is up to and where the bottleneck is.

Trying to interrupt a thread stuck in reader.readLine()

I have a connection with an IRC server over TCP. I read the data with an independent task, so far, so good. However, if I want to quit the program, I can't quit the thread because it is stuck in the reader.ReadLine() command (threadShouldRun has no impact). Using Interrupt() or Abort() doesn't appear to change anything either.
Either I need a way to determine when there are more lines to read, or I need to forcefully kill the thread (even though that's bad).
private System.Threading.Thread myThread;
private bool threadShouldRun = true;
private StreamReader reader;
private void readStream()
{
while(threadShouldRun)
{
string line = reader.ReadLine();
if (line != null)
{
newLineEvent(this, new NewLineEventArgs(line));
}
}
}
Use asynchronous calls like BeginRead as shown here and avoid the loop:
http://msdn.microsoft.com/en-us/library/system.io.stream.beginread.aspx
A solution would be to set a TimeOut on your receiving socket ( http://msdn.microsoft.com/it-it/library/system.net.sockets.socket.receivetimeout(v=vs.110).aspx ).
Once the time expires, a SocketException will be raised, so you can catch it and reiterate the control on your threadShouldRun.
In case you want to quit (and hence set threadShouldRun to false), there are two scenarios:
Data received, you will handle it, and on the next check the variable will be found false and thread will terminate;
No Data received, TimeOut happens, Exception is raised, you will handle it, and on the check the thread will terminate.

Thread.Join in UI thread also blocking child thread

This may well be a dumb question and if this has already been answered elsewhere then I'd really appreciate it if someone could point me to it as my searching hasn't turned up anything definitive.
In a nutshell, my problem is that when I do childThread.Join() in the UI thread on a child thread which has been flagged to stop the childThread seems to block as well as the main thread so everything just hangs.
That the UI will block due to using Join is not a problem in and of itself at the moment since the childThread should finish in under a second after it's told to quit anyway.
This happens while I'm waiting for a thread running a repeating process to quit before I can run another method which returns some information but can't be run at the same time as the other process.
My Winforms application is integrating with a piece of usb hardware by pinvoking the C API for the hardware.
The hardware API has a method that will start off a process that will run indefinitely and repeatedly and rapidly callback with new information which I then need to pass to the UI.
This operation can be cancelled by another call to the hardware API which sets a flag the hardware can see so it knows to quit.
I've wrapped this C API with my own C# code, and within the wrapper I've had to spin out the start process call in another thread so that the activity doesn't block the UI.
Here are the edited highlights of roughly what I'm doing.
public class DeviceWrapper
{
Thread childThread = null;
void DeviceWrapper
{
//Set the callback to be used by the StartGettingInformation() process
PInvokeMethods.SetGetInformationCallback(InformationAcquiredCallback);
}
public void StartProcess()
{
childThread = new Thread(new ThreadStart(GetInformationProcess))
childThread.Start();
}
void GetInformationProcess()
{
PInvokeMethods.StartGettingInformation();
}
//This callback occurs inside the childThread
void InformationAcquiredCallback(Status status, IntPtr information)
{
//This callback is triggered when anything happens in the
//StartGettingInformation() method, such as when the information
//is ready to be retrieved, or when the process has been cancelled.
if(status == Status.InformationAcquired)
{
FireUpdateUIEvent();
}
//If the cancel flag has been set to true this will be hit.
else if(status == Status.Cancelled)
{
//Reset the cancel flag so the next operation works ok
PInvokeMethods.SetCancelFlag(false);
childThread.Abort();
}
}
//This method runs once, and can't run at the same time as GetInformationProcess
public string GetSpecificInformation()
{
//This triggers InformationAcquiredCallback with a status of Cancelled
StopProcess();
if(childThread.IsAlive)
{
childThread.Join();
}
return PInvokeMethods.GetSpecificInformation();
}
public void StopProcess()
{
PInvokeMethods.SetCancelFlag(true);
}
}
Using this code when I call childThread.Join() the whole application grinds to a halt (which I'd expect for the UI and that's fine) and the childThread also seems to halt because the callback never gets hit again.
However, if I use the following code instead:
public string GetSpecificInformation()
{
//This triggers InformationAcquiredCallback with a status of Cancelled
StopProcess();
string s = "";
ThreadPool.QueueUserWorkItem(new WaitCallback(delegate
{
if(childThread.IsAlive)
{
childThread.Join();
}
s = PInvokeMethods.GetSpecificInformation();
}));
return s;
}
Then everything gets hit as expected and childThread does finish and all is well, except obviously my string gets returned empty before the WaitCallback fires and assigns to it.
So, do I just have to suck it up and change the class so that I use the QueueUserWorkItem and WaitCallback and fire an event to deal with my string return?
Is there something daft I'm doing in my first approach that's causing the childThread to block as well?
Or is there another tactic or class entirely that I should be using, bearing in mind it's .NET 3.5 I'm on?
Well, FireUpdateUIEvent(); sounds like a method that might Post Send to the MsgQueue (Control.Invoke()). When the main thread is waiting in a Join() then you have a classic deadlock.
In Addition, childThread.Abort() is not considered safe.
So, do I just have to suck it up and change the class so that I use the QueueUserWorkItem and WaitCallback and fire an event to deal with my string return?
I certainly would re-design it. It probably can be simplified a bit.

Categories

Resources