alexatsearidge
asked on
Threading - How can I update an image box regularily from a thread
Hi,
I have an application that receives and displays live video feed (Motion JPEG). I have a tree view so the user can select which live video feed to view. Originally the feed was displayed in an image box on my main form. It was decided that the feed should be displayed in a pop up window. This is where I have my problems.
I process the video feed in a worker thread and that is working fine. When my thread and image box were on the main form, in my worker I had the line:
mCameraView.Image = lastFrame;
This was updating just fine.
Now that I've moved the thread and image box to a seperate form, this code works, but if I move or resize the dialog it crashes. I was told that this may be due to the fact that I'm trying to access the UI from two different threads; myWorker and the original.
My solution was to save the image to a local variable instead of updating the UI directly
Call invalidate on the ImageBox
In the OnPaint update the ImageBox with the image.
Now my program is just freezing. I assume it is deadlocking somehow. Anyone know what is going on? Or if there is a better solution?
I have an application that receives and displays live video feed (Motion JPEG). I have a tree view so the user can select which live video feed to view. Originally the feed was displayed in an image box on my main form. It was decided that the feed should be displayed in a pop up window. This is where I have my problems.
I process the video feed in a worker thread and that is working fine. When my thread and image box were on the main form, in my worker I had the line:
mCameraView.Image = lastFrame;
This was updating just fine.
Now that I've moved the thread and image box to a seperate form, this code works, but if I move or resize the dialog it crashes. I was told that this may be due to the fact that I'm trying to access the UI from two different threads; myWorker and the original.
My solution was to save the image to a local variable instead of updating the UI directly
Call invalidate on the ImageBox
In the OnPaint update the ImageBox with the image.
Now my program is just freezing. I assume it is deadlocking somehow. Anyone know what is going on? Or if there is a better solution?
ASKER
Hi Alex, sorry you went over me head a little there. I have pretty much no experience in thread programming.
Control.CheckForIllegalCro ssThreadCa lls = true; <- I cannot find this method for Control
Mind putting that in laymens terms with perhaps a code example for the Invoke/BeginInvoke?
Control.CheckForIllegalCro
Mind putting that in laymens terms with perhaps a code example for the Invoke/BeginInvoke?
This is from C# 8.0:
http://msdn2.microsoft.com/en-us/library/system.windows.forms.control.checkforillegalcrossthreadcalls.aspx
What version do you use?
About BeginInvoke/Invoke:
http://www.codeproject.com/csharp/workerthread.asp
.NET doesn't allow to call Windows Forms methods from worker threads. Instead of this, we must use BeginInvoke or Invoke calls. However, .NET 1.1 developers were not consistent, and sometimes illegal cross-thread calls work successfully. Sometimes they give exception, sometimes program hangs.
For backward compatibility, .NET 2.0 supports the same behavior. However, this is undesired because program results are unpredictable.
Control.CheckForIllegalCro ssThreadCa lls = true;
It is strongly recommended to add this call to the beginning of every .NET 2.0 program. In this case every illegal call causes exception - consistent behavior. You need to fix all these exceptions by replacing direct calls with BeginInvoke or Invoke. Only after this is done, and program still hangs, search for possible deadlock.
http://msdn2.microsoft.com/en-us/library/system.windows.forms.control.checkforillegalcrossthreadcalls.aspx
What version do you use?
About BeginInvoke/Invoke:
http://www.codeproject.com/csharp/workerthread.asp
.NET doesn't allow to call Windows Forms methods from worker threads. Instead of this, we must use BeginInvoke or Invoke calls. However, .NET 1.1 developers were not consistent, and sometimes illegal cross-thread calls work successfully. Sometimes they give exception, sometimes program hangs.
For backward compatibility, .NET 2.0 supports the same behavior. However, this is undesired because program results are unpredictable.
Control.CheckForIllegalCro
It is strongly recommended to add this call to the beginning of every .NET 2.0 program. In this case every illegal call causes exception - consistent behavior. You need to fix all these exceptions by replacing direct calls with BeginInvoke or Invoke. Only after this is done, and program still hangs, search for possible deadlock.
ASKER
I'm using .NET ver 1.1
Does that mean I'm basically stuck?
I'm now using Invoke to call my method to add the image.
The form loads and the picture box streams the image successfully, but as soon as I move or resize the form my program crashes.
Does that mean I'm basically stuck?
I'm now using Invoke to call my method to add the image.
The form loads and the picture box streams the image successfully, but as soon as I move or resize the form my program crashes.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks for your help Alex,
I had some sample code that used GDI to draw the image instead of updating a picturebox. I use Monitor.Enter/Exit around the drawing code and it works fine.
I had some sample code that used GDI to draw the image instead of updating a picturebox. I use Monitor.Enter/Exit around the drawing code and it works fine.
Control.CheckForIllegalCro
In this case every direct cross-thread call causes exception immediately. Fix this by replacing direct call with Invoke and BeginInvoke.