今天用MFC+ADO给老师做项目的时候,老师要求不停的扫描数据库,一旦数据发生变化的时候,就要给他发送消息.并且将变化值交给他.
我就只好写了一个类,编了一个DLL,刚开始的时候是在这个类的构造函数中实例化的代码如下
//////////////////////////////////////// xx.h //头文件 //////////////////////////////////////// class DATA_BUS_APIC MyDatabase { public: CMyDatabase(); ~CMyDatabase(); . . . static unsigned int __stdcall XXXTheadFun(); private: static _ConnectionPtr m_pDBConnection //ADO连接指针 . . } //////////////////////////////////////// xx.cpp //源文件 //////////////////////////////////////// CMyDatabase::CMyDatabase() { . . . if (FAILED(m_pDBConnection.CreateInstance(__uuidof(Connection)))) { writeErrorLog("bool CMyDatabase::CMyDatabase()函数中数据库链接实例创建失败!"); } try { m_pDBConnection->Open((_bstr_t)m_czDBCon,"","",NULL); } catch(_com_error &e) { writeErrorLog("bool CMyDatabase::CMyDatabase()中连接失败!错误描述:",&e); } . . . }
在主程序中会有
BOOL CXXXXApp::InitInstance() { . . . if(!AfxOleInit()) { AfxMessageBox(_T("AfxOleInit()初始化失败!")); } . . . }
这里主程序的主线程中初始化了COM库,类的构造函数也在主线程中实例化了_ConnectionPtr指针,两者都在同一线程中,自然相安无事.
但是因为我们这个程序实时性要求比较高,还要求与数据库断线重连,不能过分的占用主线程,如果和数据库没有连接的情况下实例化这个类会占用5秒到6秒的时间,因为有一次连接.
后来我拿回来改,想当然的认为只要将
m_pDBConnection->Open((_bstr_t)m_czDBCon,"","",NULL);
移动到新开的线程中就没事了,此时_ConnectionPtr指针在主线程中实例化,而连接数据库在新开的线程中,这样做是不行的.无法连接到数据库.
但是将
FAILED(m_pDBConnection.CreateInstance(__uuidof(Connection)))
移动到新开的线程中,实例化又会失败.
后来想会不是是COM库的问题,去网上查了很多资料才找到解决的办法,现在记下来,省的以后忘记.
//////////////////////////////////////// xx.cpp //源文件 //////////////////////////////////////// unsigned int XXXXTheadFun() //线程回调函数 { CoInitilize(NULL); //在新的线程中初始化COM库 . . . if (FAILED(m_pDBConnection.CreateInstance(__uuidof(Connection)))) { writeErrorLog("bool CMyDatabase::XXXXTheadFun()函数中数据库链接实例创建失败!"); } try { m_pDBConnection->Open((_bstr_t)m_czDBCon,"","",NULL); } catch(_com_error &e) { writeErrorLog("bool CMyDatabase::XXXXTheadFun()中连接失败!错误描述:",&e); } . . . CoUnInitilize(); return 123; }
这样问题就解决了!