मुझे डीसीओएम पिंग सिस्टम के बारे में निश्चित नहीं है, लेकिन आपके लिए एक विकल्प केवल अधिसूचनाओं को अलग थ्रेड पूल में खेत देना होगा। यह अवरुद्ध ग्राहकों की एक छोटी संख्या होने के प्रभाव को कम करने में मदद करेगा - निश्चित रूप से बहुत अधिक होने पर आपको समस्याएं शुरू हो जाएंगी।
ऐसा करने का आसान तरीका QueueUserWorkItem
का उपयोग करना है - यह एप्लिकेशन के सिस्टम थ्रेड पूल पर पास कॉलबैक का आह्वान करेगा।
static InfoStruct {
IRemoteHost *pRemote;
BSTR someData;
};
static DWORD WINAPI InvokeClientAsync(LPVOID lpInfo) {
CoInitializeEx(COINIT_MULTITHREADED);
InfoStruct *is = (InfoStruct *)lpInfo;
is->pRemote->notify(someData);
is->pRemote->Release();
SysFreeString(is->someData);
delete is;
CoUninitialize();
return 0;
}
void InvokeClient(IRemoteHost *pRemote, BSTR someData) {
InfoStruct *is = new InfoStruct;
is->pRemote = pRemote;
pRemote->AddRef();
is->someData = SysAllocString(someData);
QueueUserWorkItem(InvokeClientAsync, (LPVOID)is, WT_EXECUTELONGFUNCTION);
}
अपने मुख्य थ्रेड एक जाँच में है, तो यह केवल थोड़ा और अधिक जटिल है,: यदि आप एक एमटीए का उपयोग कर रहे मान लिया जाये कि, यह सब आप सब करने की ज़रूरत है तुम सिर्फ CoMarshalInterThreadInterfaceInStream
और CoGetInterfaceAndReleaseStream
उपयोग करने के लिए अपार्टमेंट के बीच इंटरफेस सूचक पारित करने के लिए है:
static InfoStruct {
IStream *pMarshalledRemote;
BSTR someData;
};
static DWORD WINAPI InvokeClientAsync(LPVOID lpInfo) {
CoInitializeEx(COINIT_MULTITHREADED); // can be STA as well
InfoStruct *is = (InfoStruct *)lpInfo;
IRemoteHost *pRemote;
CoGetInterfaceAndReleaseStream(is->pMarshalledRemote, __uuidof(IRemoteHost), (LPVOID *)&pRemote);
pRemote->notify(someData);
pRemote->Release();
SysFreeString(is->someData);
delete is;
CoUninitialize();
return 0;
}
void InvokeClient(IRemoteHost *pRemote, BSTR someData) {
InfoStruct *is = new InfoStruct;
CoMarshalInterThreadInterfaceInStream(__uuidof(IRemoteHost), pRemote, &is->pMarshalledRemote);
is->someData = SysAllocString(someData);
QueueUserWorkItem(InvokeClientAsync, (LPVOID)is, WT_EXECUTELONGFUNCTION);
}
ध्यान दें कि त्रुटि जाँच स्पष्टता के लिए elided किया गया है - आप निश्चित रूप से त्रुटि के लिए सभी कॉल की जांच चाहते हैं - विशेष रूप से, आप करना चाहते हैं RPC_S_SERVER_UNAVAILABLE
और अन्य ऐसी नेटवर्क त्रुटियों के लिए जांच कर रहे हैं, और अपमानजनक ग्राहकों को हटा दें।
कुछ और परिष्कृत विविधताएं जिन्हें आप विचार करना चाहते हैं, उनमें एक ही समय में प्रति ग्राहक उड़ान में एक ही अनुरोध सुनिश्चित करना शामिल है (इस प्रकार एक अटक गए ग्राहक के प्रभाव को और कम करना) और एमटीए में मार्शल इंटरफेस पॉइंटर को कैशिंग करना (यदि आपका मुख्य धागा एक एसटीए है) - चूंकि मेरा मानना है कि CoMarshalInterThreadInterfaceInStream
नेटवर्क अनुरोध कर सकता है, तो आप आदर्श रूप से उस समय का ख्याल रखना चाहते हैं जब आप ग्राहक को अपने मुख्य धागे पर अवरुद्ध करने के जोखिम के बजाय कनेक्ट किया गया है।
क्या आपने थ्रेड पूल धागे से घटनाओं को भेजने पर विचार किया है, ताकि अवरोध को सीमित किया जा सके? – bdonlan
@bdonlan: यह एक समाधान हो सकता है, हालांकि यह सर्वर को जटिल रूप से जटिल करेगा - इसे उन अतिरिक्त धागे के जीवनकाल का ख्याल रखना होगा। – sharptooth
वास्तव में नहीं - आप केवल अंतर्निहित Win32 थ्रेड पूल का उपयोग कर सकते हैं। यदि आप पहले से ही एमटीए का उपयोग कर रहे हैं, तो QueueUserWorkItem को हिट करने के लिए यह बहुत छोटा है। यदि आप एसटीए में हैं तो आपको एमटीए में रिमोट इंटरफ़ेस में हैंडल को मार्शल करना होगा, लेकिन CoMarshalInterThreadInterfaceInStream आदि का उपयोग करना अभी भी मुश्किल नहीं है – bdonlan