01-26-2007 10:18 AM
02-23-2007 08:16 PM
You can call the IMAQ functions from multiple threads, but you need to create an ActiveX wrapper object instance per thread, and then call CreateControl on it to set the OCXState:
AxCWIMAQVision axCWIMAQVision1 = new AxCWIMAQVision();
axCWIMAQVision1.CreateControl();
You need to set the worker thread apartment state to STA to instantiate ActiveX controls in it:
Thread myThread = new Thread(myThreadProc);
myThread.SetApartmentState(ApartmentState.STA);
myThread.Start();
Before the thread exits, call dispose on the IMAQ vision object and then call Thread.CurrentThread.Join(0) to make sure the garbage collector can switch to your thread context for cleanup. CurrentThread.Join(0) behaves much like Sleep(0), but does message pumping, which is needed since the STA thread has no message pump. Calling CurrentThread.Join(0) peroidically should also make your thread responsive to Aborts.
So you end up with:
static void myThreadProc()
{
AxCWIMAQVision axCWIMAQVision1 = new AxCWIMAQVision();
axCWIMAQVision1.CreateControl();
// make some calls on axCWIMAQVision1
//...
axCWIMAQVision1.Dispose();
Thread.CurrentThread.Join(0);
}
I hope that helps,
Jamie
05-04-2007 05:12 AM
06-21-2010 10:29 AM
Anyone has a solution for how to use IMAQ ActiveX Interop under multi threading ?
For my sake, I made a dotNet 2.0 executable with multiple instances of the same form.
Each form having its own message loop. Each form also embed another STA thread that fires continuously some processing on the GUI thread (using form.invoke() ).
When I use only one form, everything is fine.
When multiple form are used. Only one form works ok. On other form the following code
AxCWIMAQVision1.MatchPattern2(l_Img_Cam, l_Img_Label, l_Process_MatchOptions, l_Process_MatchReport)
generates the exception: 'System.Reflection.TargetInvocationException' s'est produite dans mscorlib.dll
06-21-2010 10:52 AM
I found a way around the multithreading issue: when starting a new thread that will instanciate an IMAQ ActiveX, I added a sleep time of 1000 milliseconds. Don't ask my why or how .... now it works !!
It is like on the PCI-6518, between writing output leave a period of 5 millisecond otherwise the value you expect to output will never be output !
The VB2005 projects starts with NI_Form
Private Sub Form_StartNI_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
For i As Integer = 1 To 3
Dim t As New Thread(AddressOf m_fThreadProc_HMI_AppRun_Form)
t.SetApartmentState(ApartmentState.STA)
t.Start()
Threading.Thread.CurrentThread.Sleep(1000)
Next
End Sub
' The thread procedure that will soon host the message loop of a New Form
Private Shared Sub m_fThreadProc_HMI_AppRun_Form()
Dim t As New ProcessingForm
Application.Run(t)
End Sub
In the ProcessingForm:
Private Sub ProcessingForm_Form_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim t As New Thread(AddressOf m_fThreadProc)
t.IsBackground = True
t.SetApartmentState(ApartmentState.STA)
t.Start()
End Sub
Private Sub m_fThreadProc()
Dim l_Delegate2 As New m_Delegate_HMI(AddressOf m_fSimpleHMIjob)
Dim l_obj() As Object
while true
Me.Invoke(l_Delegate1, l_obj)
end while
end sub
Private Delegate Sub m_Delegate_HMI()
Private Sub m_fSimpleHMIjob()End Sub
' Here, do some NI IMAQ processing using AxCWIMAQVision1
' such as pattern matching, ....
Threading.Thread.CurrentThread.Sleep(10)
End Sub
06-21-2010 05:54 PM
It is working almost OK, except that calling method of axCWMachineVision leads to exception being thrown.
I have now one Form launching 2 background STA threads.
Processing works fine, but I don't succeed into sharing/sending processing results with the GUI thread (even through form.invoke).
I can share Images - thats ok,
But for example calling:
CWMachineVision1.DrawPatternMatch CWIMAQViewer1.Image.Overlays(1), Report(1), vbBlue
doesn't work and generate an exception.
I tried calling in both background thread and UI thread, without success.
By the way, as soon as the background thread instanciates CWMachineVision object the processing threads throws exception when calling FindPattern() ...
I guess it can be a marshalling problem (and I am not good at solving marshalling issue) or an apartment issue.
My next step is to convert the CWIMAQPatternMatchReportItem into a list of Rectangle.
And on the UI thread I will draw manually each element .... one by one 😞 but that should solve it.
06-22-2010 11:10 AM
Did you get the chance the try the native .NET API released with Vision Development Module 2009?
-Christophe
06-22-2010 12:33 PM
The ActiveX implementation is just not multi thread safe. I used seperate exe in order to overcome this one....
Secondly Vision in Labview seem to be multithreaded as well.
The new .net API shoould overcome all of this.(NI confirm this to me) But never tried it. Would be interesting to know if this works....
06-24-2010 08:18 AM
Thank you both for your answers.
Unfortunately the only VDM licence we have is for VDM 8.0.
We moved to Matrox MIL since then.
NI Viewer is still more user friendly, so one day we might move back to NI Vision
BTW (by the way):
it was my mistake; but instancitation AxCWMachineVision on a thread works fine after you call the function .CreateControl (as stated in this post).
An exception is generated. A try / catch block gets over it !
To me, now it seems that you can do multi threading with the VDM8.2 ActiveX !!