муватися угоди COM про потоки, ми повинні створити проміжний об'єкт (proxy object) для об'єкта clsBackground. Проміжний об'єкт повинен бути переданий новому потоку замість початкового об'єкта. Звернення до нового потоку на проміжному об'єкті будуть переадресовані (Marshaled) в поточний потік. p> CoMarshalInterThreadInterfaceInStream виконує цікаву задачу. Вона збирає всю інформацію, необхідну при створенні проміжного об'єкта, для певного інтерфейсу і завантажує її на об'єкт потоку (stream object). У цьому прикладі ми використовуємо інтерфейс IDispatch, тому що ми знаємо, що кожен клас Visual Basic підтримує IDispatch і ми знаємо, що підтримка переадресації (marshalling) IDispatch вбудована в Windows - так що цей код буде працювати завжди. Потім ми передаємо об'єкт потоку (stream object) новому потоку. Цей об'єкт розроблений Windows, щоб бути переданим між потоками однаковим способом, так що ми можемо безпечно передавати його функції CreateThread. Інша частина функції StartBackgroundThreadApt ідентична функції StartBackgroundThreadFree. p> Функція BackgroundFuncApt також складніше ніж її еквівалент при використанні моделі вільних потоків і показана нижче:
'A correctly marshaled apartment model callback.
'This is the correct approach, though slower.
Public Function BackgroundFuncApt (ByVal param As Long) As Long
Dim qobj As Object
Dim qobj2 As clsBackground
Dim res &
'This new thread is a new apartment, we must
'initialize OLE for this apartment
'(VB doesn't seem to do it)
res = CoInitialize (0)
'Proper apartment modeled approach
res = CoGetInterfaceAndReleaseStream (param, IID_IDispatch, qobj)
Set qobj2 = qobj
Do While Not qobj2.DoTheCount (10000)
Loop
qobj2.ShowAForm
'Alternatively, you can put a wait function here,
'then call the qobj function when the wait is satisfied 'All calls to CoInitialize must be balanced
CoUninitialize
End Function
Перший крок повинен ініціалізувати підсистему OLE для нового потоку. Це необхідно для переадресації (marshalling) коду, щоб працювати коректно. CoGetInterfaceAndReleaseStream створює проміжний об'єкт для об'єкта clsBackground і реалізує об'єкт потоку (stream object), який використовується для передачі даних з іншого потоку. Інтерфейс IDispatch для нового об'єкта завантажується в змінну qobj. Тепер можливо отримати інші інтерфейси - проміжний об'єкт буде коректно переадресовувати дані для кожного інтерфейсу, який може підтримувати.
Тепер Ви можете бачити, чому цикл поміщений в цю функцію замість того, щоб перебувати безпосередньо в об'єкті. Коли Ви вперше викличте функцію qobj2.DoTheCount, то побачите, що код виконується в початковому потоці! Кожен раз, коли Ви викликаєте метод об'єкта, Ви фактично викл...