How to avoid locking when using a static object - c#

I have a C# desktop application.
In my code I am acquiring an image from a camera. I pass this image to a routine.
This is the 'syntax' of my code:
//in a routine
if (!isProcessingMotion)
{
try
{
isProcessingMotion = true;
//do stuff
}
finally
{
isProcessingMotion = false;
}
}
//////
//module variable:
private static bool isProcessingMotion = false;
The function is reached when an event is raised from the parent code.
The trouble is the 'isProcessingMotion = false is not always 'hit'. I have put a try-catch around the whole of the code but there is no error.
I do not want to use monitor or lock('a read only static object') as when I do the app grinds down to a slow process.
What should I be looking out for?

I presume what is happening is not that the finally block isn't reached, it is that a different thread might be changing the isProcessingMotion variable after that finally block has executed. That might happen when a second event is fired, but the first event hasn't finished processing the first request.
It seems that there are multiple accesses to your field at one.
Although you prefer not to use a lock, this seems like the perfect fix for your problem.
Either that or you'll have to change your application logic to not make multiple reads to that same variable.
Edit
Since you have to process them sequentially, i'd definitely go with a lock:
var processingLock = new object();
if (!isProcessingMotion)
{
lock (processingLock)
{
isProcessingMotion = true;
// Do stuff..
isProcessingMotion = false;
}
}

Related

Is there a way to await a flag change in a function?

I've attempted to make a simple step mode for an algorithm I'm running, and here is how it looks like:
public async Task<bool> AStarAlgorithmAsync(PFSquare curr = null)
{
// some algorithm code here
foreach(var square in Sorroundings)
{
if (SteppedMode)
{
await Task.Run(Pause);
}
if (await AStarAlgorithmAsync(square))
{
return true;
}
}
}
In my application, I have a Boolean called SteppedMode that decides if the algorithm should run one iteration per click event.
Pause() looks like this:
private void Pause()
{
while (!ContinueStep) { }
ContinueStep = false;
return;
}
And in another part of my (GUI) application I have an event which sets the boolean ContinueStep to true which in theory should end the while loop and continue the algorithm function. Currently this bit of code locks my GUI thread up and I'm almost certain there is a better way to do this.
I'm trying to get my algorithm function to run one iteration, wait for a click from the user and only then continue running the algorithm. Is there an easier and cleaner way to do this?
(This is a GUI application, not a console application.)
Your property is moonlighting as a method.
It makes no sense to set a property, to then have that property revert back to its original state immediately. As a consumer, I would be majorly confused by that behavior. Think about this code:
var myObj = new MyObject();
myObj.MyBoolean = true;
Console.WriteLine(myObj.MyBoolean); // FALSE!?
It just doesn't make sense.
The only effect you want to trigger by setting this property is to execute some code. That's exactly what methods are supposed to be used for:
public void ContinueStep()
{
Console.WriteLine("I did some work");
}
So instead of this:
myObj.ContinueStep = true;
you should be doing this:
myObject.ContinueStep();
This doesn't lock up your UI thread, while also being a lot more sensical to your consumer. The method suggests that some action will be taken (which may or may not lead to state changes in the object - that's a contextual expectation).
Infinite recursion
As an aside; based on your code, AStarAlgorithmAsync is a recursive function, and seemingly infinitely so. There doesn't seem to be an ending condition.
Every recursive level will interate over the first surrounding and then trigger the next level, which again will interate over the first surrounding and then trigger the next level, which again ...
That can't be right, but it's unclear to me how to fix it as the bigger picture is not explained in your question
A simple implementation
What I'm trying to do is get my algorithm function to run one iteration, wait for a click from the user and only then continue running the algorithm, is there an easier and cleaner way to do this?
A simple example of such a thing:
private int _index = 0;
private List<object> _myList = ...; // assume this list contains some elements
public void ProcessNextObject()
{
if(_index < _myList.Length)
{
Process(_myList[_index]);
_index++;
}
}
private void Process(object o)
{
Console.WriteLine("Processing this object!");
}
You can then hook up your click event to call ProcessNextObject().
Note that in this example, the list is processed once and cannot be processed again. By manipulating the index value, you can change that behavior as you like.

Use of global var in multithreaded camera frame ready events

I am writing an application that depends on fast image manipulation. It might sound strange but I'm doing this C# and not in C++. So far this has not been a limitation, I can process an image realtime. While I do quite some complex things with the image and I do this under 30ms.
I changed the program to make sure that the image stream would never queue
by simply checking a boolean to check if a current frame is not being processed. Normally this wouldn't happen, but in some cases it did. For example when run the app in VS2010 debug mode, or when the PC is doing also other heavy tasks, and has less CPU resources.
In such case I would like to skip new frame processing, so processing them won't queue. In such cases it would be better to just work with last known data which is still being processed, and thus waiting would be the fastest method then to retrieve an answer.
So I started with something like:
private void Camera_FrameReady(object Sender, ImageEvent e)
{
if (!IsImageReady) return; // global var
IsImageReady = false;
//... do stuff with the image
IsImageReady=true;
}
This didn't workout, as I had hoped. And I think it has to do with the threading nature of events within the C# compiler. So then I tried to resolve it by de-registering and re-registering the Camera_FrameReady ready, but the camera takes to much time to restart, so that didn't workout.
Strangely now it seams to work with the code below but I'm not sure why it does.
private void Camera_FrameReady(object Sender, ImageEvent e)
{
Update_Image(e)
}
private void Update_Image(e)
{
if (!IsImageReady) return; // global var
IsImageReady = false;
//... do stuff with the image
IsImageReady=true;
}
This makes me wonder about how C# gets compiled. Does it work like that whenever Camera_FrameReady is called it has a "world view" of the current global values? Or that global variables are only updated after the processing of an event?
The first thing came in my head is that the Camera_FrameReady event blocks the acquisition thread. But that doesn't explain why the second solution works..
So if you want to process the images parallel to the acquisition thread, you should create a new thread for processing.
For example: When there is a new image, check if the processing thread is busy. If the processing thread is busy, you shouldn't wait or queue (like you wanted) but just skip this image. If the processing thread is waiting for work, store the image in a 'global' variable, so the processing thread can access it and signal the processing thread.
I made an example for you: (pseudo)
// the thread for the processing.
private Thread _processingThread;
// a signal to check if the workerthread is busy with an image
private ManualResetEvent _workerThreadIsBusy = new ManualResetEvent(false);
// request for terminating
private ManualResetEvent _terminating = new ManualResetEvent(false);
// confirm terminated
private ManualResetEvent _terminated = new ManualResetEvent(false);
// store the current image.
private Image _myImage;
// event callback for new images
private void Camera_FrameReady(object Sender, ImageEvent e)
{
// is the workerthread already processing an image? return.. (skip this image)
if (_workerThreadIsBusy.WaitOne(0))
return; // skip frame.
//create a 'global' ref so the workerthread can access it.
/* BE CAREFULL HERE. You might experience trouble with the instance of this image.
* You are creating another reference to the SAME instance of the image
* to process on another thread. When the Camera is reusing this
* image (for speed), the image might screwed-up. In that case,
* you have to create a copy!
* (personally I would reuse the image which makes the image not available outside the event callback) */
_myImage = e.Image;
// signal the workerthread, so it starts processing the current image.
_workerThreadIsBusy.Set();
}
private void ImageProcessingThread()
{
var waitHandles = new WaitHandle[] { _terminating, _workerThreadIsBusy };
var run = true;
while (run)
{
switch (EventWaitHandle.WaitAny(waitHandles))
{
case 0:
// terminating.
run = false;
break;
case 1:
// process _myImage
ProcessImage(_myImage);
_workerThreadIsBusy.Reset();
break;
}
}
_terminated.Set();
}
private void ProcessImage(Image _myImage)
{
// whatever...
}
// constructor
public MyCameraProcessor()
{
// define the thread.
_processingThread = new Thread(ImageProcessingThread);
_processingThread.Start();
}
public void Dispose()
{
_terminating.Set();
_terminated.WaitOne();
}
}
Your code is not multithreading safe
if (!IsImageReady) return; // global var
IsImageReady = false;
//... do stuff with the image
IsImageReady=true;
2 threads can read IsImageReady at the same time, see that it is true and both set it then to false. You might also get problems if the processor is reading IsImageReady from cache and not from memory. You can avoid these kind of problems with the Interlocked class, which reads and changes the value in one operation. It also ensures that the cache doesn't cause problems.
private int IsImageReady= 0;
private void Camera_FrameReady(object Sender, ImageEvent e){
int wasImageReady = Interlocked.Exchange(ref IsImageReady, 1);
if (wasImageReady ==1) return;
//do something
IsImageReady= 0;
}
}
Although I am not sure if that is your only problem. You might have also others. To be sure, you have to debug your code properly, which is very difficult when it involves multithreading. Read my article Codeproject: Debugging multithreaded code in real time how you can do it.

Thread.Join stops a threads exit (or appears too) but SpinWaiting for the thread to exit doesnt

We had a problem of some functions that need to be run against an API periodically to get information from a device and the solution I came up with uses a new object to run the thread and the object has some functions to tell the thread to terminate. The object needs to do some setup, run a periodic command and handle shutting down. It also needs to be able to run other commands interleaved with the periodic command. It has three functions that it needs when being setup (Startup, Shutdown and Periodic) and you can pass in a delegate to the command you want interleaved. The startup and periodic command, and the interleaved command, work well enough.
The problem is when trying to stop operation and terminate the thread.
The thread function that executes looks like
private void InterleaverThread()
{
if (this.StartupFunction != null)
{
this.StartupFunction();
}
this.startUpFinished = true;
while (!this.stop)
{
if (this.optCmd != null)
{
this.optCmdResult = this.optCmd();
this.optCmdFinished = true;
}
if (this.stop)
{
break;
}
this.lastPeriodicCmdResult = this.PeriodicFunction();
}
if (this.ShutdownFunction != null)
{
this.ShutdownFunction();
}
this.startUpFinished = false;
}
and the Stop command looks like
public void StopInterleaver()
{
if (!this.IsRunning())
{
return;
}
this.stop = true;
this.interleaverThread.Join();
// SpinWait.SpinUntil(this.IsRunning);
}
When the Thread.Join() command is used the thread never returns but if I used the SpinWait.SpinUntil() the StopInterleaver command returns in the time frame expected. The IsRunning() command just checks the thread IsAlive.
public bool IsRunning()
{
if (this.interleaverThread == null)
{
return false;
}
return this.interleaverThread.IsAlive;
}
The Thread is from System.Threading.
We can't figure out why .Join() doesn't return but SpinWait.WaitUntil does. It seems like they should be doing essentially the same thing.
I would suspect that the compiler is optimizing your loop and not actually checking the stop flag. That is, you have:
while (!this.stop)
{
// do stuff
}
Since the compiler sees that the value of stop can't change inside the function, it can just cache the value in a register.
One way to check if that's a problem is to mark the stop variable volatile, as in:
private volatile bool stop;
That's not a particularly robust way to do it, though. The typical way to handle things is with a CancellationToken. See Cancellation.
For a more detailed look at cancellation and an example, see Polling for Cancellation.

how to synchronise multiple threads to a common point

I want to launch an arbitrary number of threads, each executing the same method, but with different parameters. Each thread needs to block at a certain point, and wait until all threads have reached the same point. (Like racers getting into their starting blocks)
I'm stumped on how to make all threads signal to the starter that they are each ready to go.
The solution is to use Barrier Class.
i think that using locking you can synchronize the thread's access.
try this:
lock (lockThis)
{
// Access thread-sensitive resources.
}
I was struggling with multithreading too not so long ago. What you are trying to achieve can be done in a very simple way using just what you know. Here is an idea :
class MyThread
{
private Thread thread;
private bool isWaitingAtPointA = false;
private bool continueWorking = false;
public MyThread ()
{
thread = new Thread(DoMyStuff);
}
private void DoMyStuff()
{
//do stuff
//when at point A :
isWaitingAtPointA = true;
while (!continueWorking)
{
Thread.Sleep(10);
}
isWaitingAtPointA = false;
continueWorking = false;
//do more stuff
}
public bool isAtWaitingPointA()
{
return isWaitingAtPointA;
}
}
Then have a List of MyThread in your main thread that will instantiate all the MyThread objects, start their threads and also unlock them by setting from your main thread continueWorking to true.
Obviously you can check if all the threads are at point A by calling isAtWaitingPointA(). This approach is called "control variables" I believe (please someone correct me if I am wrong) and here the controls variables are the bools isWaitingAtPointA and continueWorking.
The method you want them all to use is here represented by DoMyStuff() which can be defined somewhere else to avoid code redundancies.
I hope this inspires you =)

Avoid repetitive calls to a Routine from Multiple Threads within a win form?

I have a Private object variable within a Windows form which has performs the tcp/IP socket connection and keeps the connection opened.
On form_load this object is initialized and the form has 15-20 Threads running continously within it which access this object. There are scenarios where in which the Tcp/Ip connection might be lost. SO whenever i find that the connection is lost i call the ReconnectToSocket() Method within the thread. I am performing the below code to ensure that the ReconnectToSocket() method is only called once by using _ReconnectingSocket property. But after checking the Text Log files i found out that this method is called within each sub thread's.
How can i make sure that this method is called only once and avoid repetitive calls.
Below is my code. I am interested in any alternative approach, because i feel that this is not the right approach in doing so.
bool _bReconnectingSocket = false;//To check if it is currently reconnecting
readonly object lock_reconnectSocket = new object();
private bool _ReconnectingSocket
{
get
{
lock (lock_reconnectSocket)
{
return this._bReconnectingSocket;
}
}
set
{
lock (lock_reconnectSocket)
{
this._bReconnectingSocket = value;
}
}
}
private void ReconnectToSocket()
{
if (!this._ReconnectingSocket)
{
this._ReconnectingSocket = true;
//Each sub thread checks for this variable while looping and exits from the infinite loop
this._Stop = true;
//Join all the Sub Threads Before Reconnecting
foreach (SocketThread thrd in this._subThreadCol)
{
try
{
this._objLog.WriteInfo(string.Format("Joining Subthread - {0} for Reconnecting.", thrd.ThrdID));
thrd.Join();
}
catch { }
}
this.ConnectSocket();
this._ReconnectingSocket = false;
this._Stop = false;
}
}
Try to write something like that in your class. Your routine still might be called several times, but its actual body will be executed only once at a time, if reconnected field is false.
bool reconnected = false;
object lockObject = new object();
void ReconnectToSocket()
{
lock(lockObject)
{
if(!reconnected) { /*do stuff*/; reconnected = true; }
}
}
Hi the object you lock against should be static private of the class and not an instance member. One thing I am not sure about is why you are sharing same connection among threads instead of having each thread to open, consume and immediately close its own one like we would do with a SqlConnection.

Categories