長話短說:在C#應用程序與COM進程內服務器(DLL)的作品,我會遇到‘0x80010100:系統調用失敗’異常,並在調試模式下也ContextSwitchDeadlock例外。0x80010100:系統調用失敗」的例外,ContextSwitchDeadlock
現在,在細節更:
1)C#應用程序初始化STA,創建一個COM對象(登記爲「單元」);然後在訂閱了它的連接點,並開始與該對象工作
2)在某些階段的COM對象產生了很多的事件,作爲參數傳遞COM objec非常大集合ts,它們在同一個房間中創建。
3)C#一側的事件處理程序處理上述收集,偶爾調用對象的一些方法。在某些階段,由於上述例外情況,後者的通話開始失敗。
在COM端公寓使用一個隱藏的窗口,其Winproc傳看起來是這樣的:
typedef std::function<void(void)> Functor;
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case AM_FUNCTOR:
{
Functor *f = reinterpret_cast<Functor *>(lParam);
(*f)();
delete f;
}
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
事件被髮布到從COM服務器的其他部分窗口:
void post(const Functor &func)
{
Functor *f = new Functor(func);
PostMessage(hWind_, AM_FUNCTOR, 0, reinterpret_cast<LPARAM>(f));
}
的事件是與實際參數綁定的標準ATL CP實現,並且它們歸結爲如下所示:
pConnection->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, ¶ms, &varResult, NULL, NULL);
在C#中的處理程序是這樣的:
private void onEvent(IMyCollection objs)
{
int len = objs.Count; // usually 10000 - 25000
foreach (IMyObj obj in objs)
{
// some of the following calls fail with 0x80010100
int id = obj.id;
string name = obj.name;
// etc...
}
}
==================
因此,可以將上述問題發生,只是因爲消息公寓的排隊裝滿了它試圖提供的事件?或者消息循環應該被完全阻塞以導致這樣的行爲?
讓我們假設該消息隊列有一個評價爲「的onEvent」呼2個連續的事件。第一個輸入C#託管代碼,該代碼嘗試重新輸入非託管代碼,同一個公寓。通常情況下,這是允許的,我們做了很多。何時,在什麼情況下它可能會失敗?
謝謝。
這通常是COM服務器崩潰造成的,通常是由AccessViolation引起的。您需要調試服務器。 – 2012-02-21 13:40:06
@Hans Passant正如我所提到的,我的服務器是dll,我通過啓用「調試非託管代碼」來與C#應用程序一起調試它。不,沒有任何內部崩潰的dll。 – 2012-02-21 22:08:00