продожение, начало
смАвтор:
Дата: 13.04.03
Ситуация: у меня есть главный STA поток, пул потоков-worker'ов, а также один поток, который считывает новых пользователей и создает для них ADO Conenctions. Все эти потоки создаются из main STA. В главном потоке я набиваю атрибуты объекта и ставлю этот объект-задание в очередь для обработки каким-то потоком из пула. Первый свободный поток берет этот объект для обработки.
Объекты Connection для существующих пользователей создаются в main STA потоке, для новых — в другом, отдельном потоке. Эти объекты передаются между потоками в глобальной переменной m_UserCalendars типа typedef map<CString,_CalendarPaths> UserCalendars;
1. код добавления объекта в глобальн. переменную:
bool CCreateAppointment::SetUserCalendars(const CString &Email)
{
_ConnectionPtr m_Connection(__uuidof(Connection));
_CalendarPaths* calendarPaths = new _CalendarPaths();
if (!ConnectToMailbox(m_aMailBox,"MAILTO:" + Email)) return false;
_bstr_t bstrURLItem = m_aMailBox->Calendar;
m_Connection->Provider = "ExOLEDB.DataSource";
m_Connection->Open(bstrURLItem,bstr_t(),bstr_t(),-1);
DWORD dwCookie;
HRESULT hRes = CoCreateInstance(CLSID_StdGlobalInterfaceTable, NULL, CLSCTX_INPROC_SERVER,
IID_IGlobalInterfaceTable, (LPVOID*)&pGIT);
_ASSERT(SUCCEEDED(hRes) && pGIT);
// store interface in GIT
hRes = pGIT->RegisterInterfaceInGlobal(m_Connection, IID__Connection, &dwCookie);
calendarPaths->CalendarURL = bstrURLItem;
calendarPaths->connectionCookie = dwCookie;
m_UserCalendars.insert(pair<CString,_CalendarPaths>(Email,*calendarPaths));
delete calendarPaths;
return true;
}
2. код считывания из глобальн. переменной.
bool CCreateAppointment::GetUserCalendar(const CString& Email,_CalendarPaths* CalendPaths)
{
map<CString,_CalendarPaths>::iterator userCalendarIt;
// searches connections in the map by user email, if there nothing was found,
// tries to connect to mailboxes
for (int i=0; i<2; i++)
{
userCalendarIt = m_UserCalendars.find(Email);
if (userCalendarIt != m_UserCalendars.end())
{
*CalendPaths = (*userCalendarIt).second;
return true;
}
else
SetUserCalendars(Email);
}
TRACER.Print(LOG_ERROR, _T("CCreateAppointment::GetUserCalendar, obtaining the connection to the users mailbox failed"));
return false;
}
+ функция
_ConnectionPtr _CalendarPaths::getConnection()
{
DWORD dwCookie = _CalendarPaths::connectionCookie;
_ConnectionPtr pConnection = NULL;
// get proxy to interface from GIT
HRESULT hRes = pGIT->GetInterfaceFromGlobal(dwCookie, IID__Connection, (LPVOID*)&pConnection);
if (pConnection == NULL) TRACER.Print(LOG_ERROR,_T("_CalendarPaths::getConnection(), couldn't get the Connection"));
return pConnection;
}
все потоки выполняются в одном процессе.
Проблема в том, что когда я пытаюсь взять Connection внутри какого-то worker thread, то выдается ошибка:
The application called an interface that was marshalled for a different thread
объясните пожалста, из-за чего может быть ошибка? я думал что интерфейс, записанный в GIT потом можно будет прочитать из любого потока, но .. что-то не так. Еще, если в программе не делать пул потоков, а передавать Connection с помощью GIT в главный STA, то все работает нормально.