It's better to make an AxDll (apartment threading) and create an object for each IOCP thread. I wouldn't recommend to use Std-EXE threading because you lose the debugging ability (each IOCP thread sleeps in most time). Of course you could use a small asm thunk (the cycle with GetQueuedCompletionStatus call) to transmit the data from an IOCP thread to the main thread using my module as well. Regarding to AxDll approach, i had the experience with such approach when i needed to run several instances of ActiveScripting engines simultaneously:
Code:Public Function ThreadProc( _ ByRef tData As tThreadData) As Long Dim hWnd As Long Dim tMsg As MSG Dim lRet As Long Dim pObj As Long If tData.hr < 0 Then Exit Function hWnd = tData.hWnd pObj = tData.pObjectRaw Do lRet = GetMessage(tMsg, 0, 0, 0) If lRet = -1 Then ' // Error tData.hr = E_FAIL Exit Do ElseIf lRet = 0 Then ' // Exit message queue Exit Do Else TranslateMessage tMsg DispatchMessage tMsg End If Loop While True If tData.pObjectRaw Then vbaObjSetAddref pObj, ByVal 0& End If End Function Public Function ThreadInitProc( _ ByRef tData As tThreadData) As Long Dim hr As Long Dim tClsId As UUID ' // Create communication window tData.hWnd = CreateWindowEx(0, THREAD_WND_CLASS, vbNullString, 0, 0, 0, 0, 0, HWND_MESSAGE, 0, tData.hInstance, ByVal 0&) If tData.hWnd = 0 Then hr = E_FAIL GoTo exit_proc End If tData.lThreadID = GetCurrentThreadId() tData.hThread = OpenThread(SYNCHRONIZE, 0, tData.lThreadID) hr = CLSIDFromProgID(tData.sProgID, tClsId) If hr < 0 Then GoTo exit_proc ' // Create object hr = CoCreateInstance(tClsId, Nothing, CLSCTX_INPROC_SERVER, IID_IUnknown, tData.pObjectRaw) If hr < 0 Then GoTo exit_proc ' // Marshal hr = CoMarshalInterThreadInterfaceInStream(tData.tIID, ByVal tData.pObjectRaw, tData.pStream) If hr < 0 Then GoTo exit_proc tData.bInitialized = True exit_proc: If hr < 0 Then If tData.pStream Then vbaObjSetAddref tData.pStream, ByVal 0& End If If tData.hThread Then CloseHandle tData.hThread tData.hThread = 0 End If If tData.lThreadID Then tData.lThreadID = 0 End If If tData.pObjectRaw Then vbaObjSetAddref tData.pObjectRaw, ByVal 0& End If tData.bInitialized = False If tData.hWnd Then DestroyWindow tData.hWnd tData.hWnd = 0 End If End If tData.hr = hr End Function ... Public Sub CreateObjectInThread( _ ByRef sProgID As String) Dim hr As Long Dim cObj As Object If m_tThreadData.hThread Then Err.Raise 5, "CThreadItem::CreateObjectInThread", "There is an active object in the thread" End If With m_tThreadData .sProgID = sProgID .tIID = IID_IDispatch .hInstance = App.hInstance .hr = 0 .hThread = 0 .hWnd = 0 .lThreadID = 0 .pObjectRaw = 0 .pStream = 0 End With hr = SHCreateThread(AddressOf ThreadProc, m_tThreadData, CTF_COINIT_STA, AddressOf ThreadInitProc) If hr < 0 Then Err.Raise hr If m_tThreadData.hr Then Err.Raise m_tThreadData.hr hr = CoGetInterfaceAndReleaseStream(ByVal m_tThreadData.pStream, IID_IDispatch, cObj) If hr < 0 Then Err.Raise hr Set m_cObjInThread = cObj End Sub




Reply With Quote