Measurement Studio for .NET Languages

cancel
Showing results for 
Search instead for 
Did you mean: 

Setting SynchronizeObject for classes not in forms

The AsynchReadWrite sample uses this code for VS2003

//For .NET Framework 1.1, set SynchronizingObject to the Windows Form to specify

//that the object marshals callbacks across threads appropriately.

mbSession.SynchronizingObject =

this;

where this is the form that this code resides in.

I am writing an app with lower level classes(eg Oven.cs)  that will have the serial sessions defined in them.  The Form is not available, and 'this' in Oven.cs gives a compiler error :

 Cannot implicitly convert type 'ReceiveSerial.Oven' to 'System.ComponentModel.ISynchronizeInvoke'

I am seeing somewhat random errors and deadlocks that I suspect are related to commenting this line out.  What objects can be coverted to ISynchronizeInvoke ?  Or, can I write supporting code into my Oven class that will keep the object synchronized.

This looks easier in VS2005; but I am stuck with my client's VS2003 license at this point.

 

Tom

 

0 Kudos
Message 1 of 6
(5,208 Views)

It sounds like you may be receiving undefined behavior as explained in the National Instruments -> VISA -> Documentation -> NI-VIAS .NET Framework 2.0 Help section:

ms-help://NI.MeasurementStudio.2005/NINETMain/XML/Events_Callbacks_ThreadSafety.html

"Since Windows Forms controls can only be accessed from the UI thread, you cannot access Windows Forms controls in your callback if you set SynchronizeCallbacks to false. Accessing Windows Forms controls from threads other than the UI thread results in undefined behavior. In .NET Framework 2.0, some Windows Forms controls throw exceptions when accessed from other threads."

 

Regards,

John E.
Applications Engineering
National Instruments
0 Kudos
Message 2 of 6
(5,187 Views)
Hi Tom,


Every UI object ( Controls, Forms, etc. ) implements ISynchronizeInvoke.  If your Oven class accesses UI objects indirectly via event callbacks or directly with method calls, you could experience problems if execution of the calls is not in the same thread as the UI object.  A couple of ideas:

- Provide a SynchronizingObject property in your Oven class that would be a pass-through to the mbSession.SynchronizingObject.  If your main form, or some other UI object creates the Oven, it would set the property... Oven.SynchronizingObject = form, etc.


or,


In your Oven class, use Application.OpenForms[0]:

if( Application.OpenForms.Count > 0 )
    mbSession.SynchronizingObject = Application.OpenForms[0];



- Dave

0 Kudos
Message 3 of 6
(5,174 Views)

Thanks guys.

My Oven class does indeed throw an event up to the Main form - which then updates a NI graph component, LEDs, and the like. It works almost all of the time-- but I don't trust it.

What code do I need in the Oven class to enable a SynchronizationObject property?  Is there an example installed with a similar architecture?

0 Kudos
Message 4 of 6
(5,163 Views)
Here's a quick example...


    public class Oven : ISynchronizeCallbacks
    {
        System.ComponentModel.ISynchronizeInvoke syncObject = null;

        public System.ComponentModel.ISynchronizeInvoke SynchronizingObject
        {
            get
            {
                return syncObject;
            }
            set
            {
                // mbSession needs to be set first
                if( mbSession != null )
                   mbSession.SynchronizingObject = value;
                syncObject = value;
            }
        }

       ...... your code here

    }

    public class MyForm : Form
    {
        Oven oven;

        public MyForm()
        {
            oven = new Oven();
            oven.SynchronizingObject = this;
        }
    }

0 Kudos
Message 5 of 6
(5,156 Views)

Thanks, Dave

That seems to have done the trick. I won't know for sure until it runs a couple of hours.

Tom

0 Kudos
Message 6 of 6
(5,136 Views)