Почему вызов класса Managed c ++ не ожидает его завершения sh? - PullRequest
1 голос
/ 18 апреля 2020

Допустим, у нас есть такая ситуация:

// Реализация Idl-файла

[
  object,
  uuid(44E43325-D296-4875-8473-88E1076BA98A),
  helpstring("INativeCpp Interface"),
  pointer_default(unique)
]

interface INativeCpp : IDispatch
{
   [id(1)] HRESULT ExecuteCommand([in] long CommandID);
}

library NativeCppLib
{
    importlib("stdole32.tlb");
    importlib("stdole2.tlb");

    [
       uuid(98D53837-D12A-439B-AA1B-2B838EEF30CF),
       helpstring("NativeCppClass")
    ]
    coclass NativeCpp
    {
       [default] interface INativeCpp;
    };
}

// Собственный C ++

//I had to define this interface with the same method as INativeCpp com interface as I was having some access dilemma. So, i defined this interface at the common location which NativeCpp class and ManagedCpp class both can access.
class NativeCppInterface
{
 public:
    NativeCppInterface();
    virtual ~NativeCppInterface();
    virtual HRESULT ExecuteCommand(long CommandID) = 0;
}

enum enCommands
{
     Save = 1,
     Refresh = 2
}

class ATL_NO_VTABLE NativeCpp:
  public CComObjectRootEx<CComSingleThreadModel>,
  public CComCoClass<NativeCpp, &CLSID_NativeCpp>,
  public IDispatchImpl<INativeCpp, &IID_INativeCpp, &LIBID_NativeCppLib>,
  public NativeCppInterface
{
   STDMETHODIMP ExecuteCommand(long CommandID)   //Takes around 2 minutes.
   {
      switch (enCommands(CommandID))
      {
         case enCommands::Save:
           if (!!_pSaveHandler)
           {
              _pSaveHandler->OnExecute();  //Executes some sequential methods and then launches one window. And then proceeds.
           }
           break;
         case enCommands::Refresh:
            if (!!_pPropertiesHandler)
            {
                    GetObjectDeatilsList(4);    //Executes some sequential methods. Nothing special.
            }
            break;
         default:
            break;
       }
       return S_OK;
    }
}

// Управляемый C ++ ( скомпилировать с параметром / clr)

public ref class ManagedCpp : IWrapper
{
  NativeCppInterface* native;
  ManagedCpp(NativeCppInterface* ptr)
  {
    native = ptr
  }
  void ExecuteCommand(int64_t CommandID)
  {
     native->ExecuteCommand((long)CommandID);
  }
}

// C# Project

public interface IWrapper
{
  void ExecuteCommand(long CommandID);
}

public class MainClass
{
  IWrapper _wrapper;

  MainClass(IWrapper wrapper)
  {
    _wrapper = wrapper;
  }

  void DoOperation()
  {
    _wrapper.ExecuteCommand(1);
    int nextline = 5;
  }
}

Теперь, когда я звоню DoOperation(), вызов переходит на ExecuteCommand() Native Cpp но до завершения ExecuteCommand() выполнение кода C# переходит к выполнению int nextline = 5;. Он не ждет, пока ExecuteCommand() закончит sh. Это почему? И что я могу сделать, чтобы он подождал?

Примечание: я пробовал using System.Windows.Application.Current.Dispatcher.Invoke(). Это делает трюк. Но если связь с Managed Cpp частая, то иногда Dispatcher получает слишком много вызовов и зависает. Итак, я хотел бы знать, почему вызов Managed Cpp запускается асинхронно с самого начала?

Также я хочу запустить окно UI из метода ExecuteCommand(), поэтому я действительно хочу вызвать его метод точно в потоке C# код работает.

...