Допустим, у нас есть такая ситуация:
// Реализация 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# код работает.