0

Here is my code, a simplified version

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using RDSCOMMUNICATORLib;
using System.Timers;
using System.Threading;

namespace RDSConsoleApplication
{
    class Program
    {
    static public RDSComClass oObj = new RDSComClass();


    static void Main(string[] args)
    {
        try
        {
            oObj.Host = "127.0.0.1";
            oObj.Port = 2902;

            oObj.LoadPiece(); // OK HERE 

            IConnectionEvents_OnPieceEventHandler PieceArraved = new IConnectionEvents_OnPieceEventHandler(oObj_OnPiece);
            oObj.OnPiece += PieceArraved;

        }
        catch (Exception e)
        {
            Console.WriteLine("{0} Exception caught.", e);
        }

    } // end main


    static public void oObj_OnPiece(int lLSCRef, string strLSCName, int lPieceNumber, int bWithScans)
    {

        try
        {
            // HERE WE START GETTING EXCEPTION "Unable to cast COM object of type.....
            // The application called an interface that was marshalled for a different thread"
            oObj.LoadPiece(); 
        }
        catch (Exception e)
        {
            Console.WriteLine("{0} Exception caught.", e);
        }

    }

} // end class Program
} // end namespace

I am referencing a COM object inside C# console application that serves as a gateway to connect to the back end and periodically receive some "piece" objects.

As a test, when I try from within the main method all works fine: I can connect, receive "piece" object and access its properties. The problem is that I need to receive and process that same "piece" object from within oObj_OnPiece callback method, and it throws the above mentioned exception. I browsed other similar posts, I understand it's a threading issue, but not sure how to resolve it. Any help is appreciated.

user2217057
  • 237
  • 3
  • 17
  • Can you try to add an [STAThread] attribute on Main? https://stackoverflow.com/questions/1361033/what-does-stathread-do – Simon Mourier Aug 24 '17 at 06:35
  • I did, it simply prevented the callback oObj_OnPiece to be triggered. I need to access the "piece" object inside the callback. The issue here is that the main method and the callback are being run on two different threads. If I could run them on a single thread, but at the same time be able to trigger the callback, that should solve the issue. – user2217057 Aug 24 '17 at 19:57

1 Answers1

0

You try to query an interface, which is already in use in a different thread in your application. In your case you have queried by your call the interface in your main-thread first. I guess this is the first thread.

Is it possible that the eventhandler is opening a different thread to deal with the event? If this is the case ( just check this by adding one breakpoint in your event-handler before trying to access the interface , start your program and check if there a 2 threads running ).

What you have to do is: ensure that you query your interface only in one thread by removing the first call to your COM-object.

KimKulling
  • 2,654
  • 1
  • 15
  • 26
  • I agree, but the issue with querying the interface only in one thread is that there is a dependency on an event in the first thread oObj.OnPiece += PieceArraved. This is the point when the callback is periodically triggered. And at the same time, I need to access some properties of the oObj in the callback itself for further processing. – user2217057 Aug 24 '17 at 20:20
  • What about defining a thread for the com-object and communicate via a dispatcher? – KimKulling Aug 24 '17 at 20:52