Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# COM Objects and Multithreading

i am currently developing an windows form application, which communicates with a serial device. The vendor of the device offers a *.dll file including methods for interacting. I added a reference to *.dll file in visual studio.
If i call a function of device library (Get()), i get a response after 2 seconds. To avoid freezing my GUI, i spawn a new thread, which initializes a new instance of the library object and calls the Get()-Method.
However, calling Get() freezes my GUI for exactly 2 seconds. It seems like the object is already initialized in the main thread.
I don't know what i missed in my code. Here comes a snippet of code reproducing my problem:

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            MyDevice deviceObj = new MyDevice();
            Thread myThread = new Thread(new ThreadStart(deviceObj.getValues));

            myThread.IsBackground = true;
            myThread.SetApartmentState(ApartmentState.STA);
            myThread.Start();
        }
    }

    class MyDevice
    {
        public void getValues()
        {

            // initialize object of device library
            Tcddka.tcddk tcd = new Tcddka.tcddk();

            // (comPort, identifier, timeout)
            tcd.Init((Int16)(3 - 1), "deviceID", 7000);

            for (int i = 0; i < 10; i++)
            {
                tcd.Get(); // measure new values
                Thread.Sleep(2000);
            }
        }
    }



Thank you in advance for your efforts,
Michael

EDIT: Solution

  1. Implement STAThread, derive your own class of it. Override Initialize() (don't forget to call base.Initialize() and create your COM Object here)
  2. My DLL-Library wasn't registered. Open command line, type in regsvr32 "path to your DLL file"
  3. Open registry, search for your DLL file name, browse to folder InprocServer32 and check if the ThreadingModel is set to Apartment.

Thank you guys !!

like image 766
Michael Avatar asked Feb 04 '26 00:02

Michael


1 Answers

I would first check whether the COM component has threading model set in the registry. If the ThreadingModel is not set, the component is created always in the first STA thread. In that case you should contact the component author about this issue. Sure you can set the ThreadingModel to "Apartment" by yourself but I would use it only as temporary fix while waiting the component author to fix the registration.

You must still create the component in another STA thread as Hans Passant suggested.

like image 198
mgronber Avatar answered Feb 06 '26 13:02

mgronber



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!