?? visual c++多線程dao處理 .txt
字號:
Visual C++多線程DAO處理
在DAO多線程處理中,有許多局限性,所以我設(shè)計(jì)了這么一個類,通過GUI線程來使用DAO的強(qiáng)制調(diào)用。在類中使用了GUI的消息隊(duì)列,所有進(jìn)入到CMultiDAORecordset的調(diào)用都被迫使用AfxGetThread()來檢查當(dāng)前的線程。GUI線程指針是放在InitInstance的首端,如果在GUI線程中,引入的調(diào)用請求不在運(yùn)行,那么CMultiDAORecordSet就會發(fā)送一個WM_MULTIDAOMESSAGE消息給AfxGetMainWnd()(在Mainfrm.cpp中)。Mainfrm接受到這個消息,線程也就要再運(yùn)行一次,這個時候,消息已經(jīng)接受了,基類CDaoRecordset也就得到了調(diào)用。所以你的類是從CMultiDAORecordset繼承的,而不是CDaoRecordset,如下:
class CMySet : public CMultiDaoRecordSet
在相應(yīng)的CPP文件中也應(yīng)該改一下:
IMPLEMENT_DYNAMIC(CMySet, CMultiDaoRecordSet)
CMySet::CMySet (CDaoDatabase* pdb) : CMultiDaoRecordSet(pdb)
為了處理接受到的WM_MULTIDAOMESSAGE消息,下面的代碼還應(yīng)該加在MainFrm中:
在MainFrm.h文件中加:
#ifdef MAINFRAME_CPP
UINT WM_MULTIDAOMESSAGE = RegisterWindowMessage("WM_MULTIDAOMESSAGE");
#else
extern UINT WM_MULTIDAOMESSAGE;
#endif
afx_msg LONG OnMultiDaoMessage( UINT uParam, LONG lParam);
在MainFrm.cpp文件中加:
#define MAINFRAME_CPP
#include "MutliDaoRecordset.h"
//added to the message map
BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
ON_REGISTERED_MESSAGE(WM_MULTIDAOMESSAGE, OnMultiDaoMessage)
END_MESSAGE_MAP()
//this function added
LONG CMainFrame::OnMultiDaoMessage( UINT uParam, LONG lParam)
{
//jtm
//based on switch, perform operation...
CMultiDaoRecordSet *pSet = (CMultiDaoRecordSet *)lParam;
LONG lRet = 0;
CString cRet = "";
COleVariant cVar;
try
{
//jtm-------debug--------------------------------------
CString cTraceMessage = cDAOMessageArray[uParam];
cTraceMessage += "\n";
TRACE(cTraceMessage);
//jtm-------debug--------------------------------------
switch(uParam)
{
case MultiDaoOpen:
pSet->Open();
break;
case MultiDaoClose:
pSet->Close();
break;
case MultiDaoIsOpen:
lRet = (LONG)pSet->IsOpen();
break;
case MultiDaoIsBOF:
lRet = (LONG)pSet->IsBOF();
break;
case MultiDaoIsEOF:
lRet = (LONG)pSet->IsEOF();
break;
case MultiDaoIsDeleted:
lRet = (LONG)pSet->IsDeleted();
break;
case MultiDaoIsFieldDirty:
lRet = (LONG)pSet->IsFieldDirty(pSet->pParam1);
break;
case MultiDaoIsFieldNull:
lRet = (LONG)pSet->IsFieldNull(pSet->pParam1);
break;
case MultiDaoIsFieldNullable:
lRet = (LONG)pSet->IsFieldNullable(pSet->pParam1);
break;
case MultiDaoGetName:
cRet = pSet->GetName();
lRet = (LONG)&cRet;
break;
case MultiDaoGetType:
lRet = (LONG)pSet->GetType();
break;
case MultiDaoGetEditMode:
lRet = (LONG)pSet->GetEditMode();
break;
case MultiDaoGetLastModifiedBookmark:
cVar = pSet->GetLastModifiedBookmark();
lRet = (LONG)&cVar;
break;
case MultiDaoGetRecordCount:
lRet = (LONG)pSet->GetRecordCount();
break;
case MultiDaoMoveNext:
pSet->MoveNext();
break;
case MultiDaoMovePrev:
pSet->MovePrev();
break;
case MultiDaoMoveFirst:
pSet->MoveFirst();
break;
case MultiDaoMoveLast:
pSet->MoveLast();
break;
case MultiDaoMove:
pSet->Move(*(LONG *)pSet->pParam1);
break;
case MultiDaoFindNext:
lRet = (LONG)pSet->FindNext(*(LPCTSTR *)pSet->pParam1);
break;
case MultiDaoFindPrev:
lRet = (LONG)pSet->FindPrev(*(LPCTSTR*)pSet->pParam1);
break;
case MultiDaoFindFirst:
lRet = (LONG)pSet->FindFirst(*(LPCTSTR *)pSet->pParam1);
break;
case MultiDaoFindLast:
lRet = (LONG)pSet->FindLast(*(LPCTSTR *)pSet->pParam1);
break;
case MultiDaoFind:
lRet = (LONG)pSet->Find(*(LONG *)pSet->pParam1, *(LPCTSTR*)pSet->pParam2);
break;
case MultiDaoGetBookmark:
cVar = pSet->GetBookmark();
lRet = (LONG)&cVar;
break;
case MultiDaoSetBookmark:
pSet->SetBookmark(*(COleVariant*)pSet->pParam1);
break;
case MultiDaoAddNew:
pSet->AddNew();
break;
case MultiDaoEdit:
pSet->Edit();
break;
case MultiDaoUpdate:
pSet->Update();
break;
case MultiDaoDelete:
pSet->Delete();
break;
case MultiDaoCancelUpdate:
pSet->CancelUpdate();
break;
case MultiDaoRequery:
pSet->Requery();
break;
}
}
catch (CDaoException *e)
{
TRACE("Database Multithread Operation Failed%s\n",
e->m_pErrorInfo->m_strDescription);
}
return lRet;
}
下面的代碼是加在對應(yīng)的應(yīng)用程序?qū)ο蟮念^文件中的:
public:
CWinThread *pGUIThread;
And this to the constructor in the app .cpp file:
CMyApp::CMyApp()
{
pGUIThread = AfxGetThread();
}
如果沒有上面的定義的話,你的應(yīng)用程序就會出問題。整個DAO公共函數(shù)并沒有全部實(shí)現(xiàn),但不管怎么樣,上面的函數(shù)是保護(hù)CDaoRecordset的使用的。如果你要加個函數(shù)的話,加進(jìn)去就行了,你也可以用一個對話框來顯示錯誤信息,它們都應(yīng)該在MultiDaorecordset.h中被定義。為了支持DAO多線程的類,下面的代碼也應(yīng)該加進(jìn)去:
加在Multidaorecordset.cpp中:
// MultiDaoRecordSet.cpp : implementation file
//
#define MULTIDAORECORDSET_CPP
#include "stdafx.h"
#include "MyApp.h"
#include "MultiDaoRecordSet.h"
#include "mainfrm.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CMultiDaoRecordSet
IMPLEMENT_DYNAMIC(CMultiDaoRecordSet, CDaoRecordset)
CMultiDaoRecordSet::CMultiDaoRecordSet(CDaoDatabase* pdb)
: CDaoRecordset(pdb)
{
//{{AFX_FIELD_INIT(CMultiDaoRecordSet)
//}}AFX_FIELD_INIT
m_nDefaultType = dbOpenDynaset;
}
//jtm
//thread safe destructor....
CMultiDaoRecordSet::~CMultiDaoRecordSet()
{
if (IsOpen())
Close();
// Clean up database if necessary
if (m_pDatabase != NULL && (m_nStatus & AFX_DAO_IMPLICIT_DB))
{
m_pDatabase->Close();
delete m_pDatabase;
m_pDatabase = NULL;
}
}
CString CMultiDaoRecordSet::GetDefaultDBName()
{
CMyApp *pApp = ((CMYApp *)AfxGetApp());
return pApp->GetDatabaseFullPath();
}
/////////////////////////////////////////////////////////////////////////////
// CMultiDaoRecordSet diagnostics
//jtm
//multi thread safe functoins
void CMultiDaoRecordSet::Open(int nOpenType, LPCTSTR lpszSQL, int nOptions)
{
CMYApp *pApp = ((CMYApp *)AfxGetApp());
if (pApp->pGUIThread == AfxGetThread())
{
CDaoRecordset::Open(nOpenType, lpszSQL, nOptions);
}
else
{
pParam1 = (void *)&nOpenType;
pParam2 = (void *)lpszSQL;
pParam3 = (void *)&nOptions;
AfxGetMainWnd()->SendMessage(WM_MULTIDAOMESSAGE, MultiDaoOpen, (LPARAM)this);
}
}
void CMultiDaoRecordSet::Close()
{
CMYApp *pApp = ((CMYApp *)AfxGetApp());
if (pApp->pGUIThread == AfxGetThread())
{
CDaoRecordset::Close();
}
else
{
AfxGetMainWnd()->SendMessage(WM_MULTIDAOMESSAGE, MultiDaoClose, (LPARAM)this);
}
}
BOOL CMultiDaoRecordSet::IsOpen()
{
CMYApp *pApp = ((CMYApp *)AfxGetApp());
if (pApp->pGUIThread == AfxGetThread())
{
return CDaoRecordset::IsOpen();
}
else
{
return (BOOL)AfxGetMainWnd()->
SendMessage(WM_MULTIDAOMESSAGE, MultiDaoIsOpen, (LPARAM)this);
}
}
BOOL CMultiDaoRecordSet::IsBOF()
{
CMYApp *pApp = ((CMYApp *)AfxGetApp());
if (pApp->pGUIThread == AfxGetThread())
{
return CDaoRecordset::IsBOF();
}
else
{
return (BOOL)AfxGetMainWnd()->
SendMessage(WM_MULTIDAOMESSAGE, MultiDaoIsBOF, (LPARAM)this);
}
}
BOOL CMultiDaoRecordSet::IsEOF()
{
CMYApp *pApp = ((CMYApp *)AfxGetApp());
if (pApp->pGUIThread == AfxGetThread())
{
return CDaoRecordset::IsEOF();
}
else
{
return (BOOL)AfxGetMainWnd()->
SendMessage(WM_MULTIDAOMESSAGE, MultiDaoIsEOF, (LPARAM)this);
}
}
BOOL CMultiDaoRecordSet::IsDeleted()
{
CMYApp *pApp = ((CMYApp *)AfxGetApp());
if (pApp->pGUIThread == AfxGetThread())
{
return CDaoRecordset::IsDeleted();
}
else
{
return (BOOL)AfxGetMainWnd()->
SendMessage(WM_MULTIDAOMESSAGE, MultiDaoIsDeleted, (LPARAM)this);
}
}
BOOL CMultiDaoRecordSet::IsFieldDirty(void* pv)
{
CMYApp *pApp = ((CMYApp *)AfxGetApp());
if (pApp->pGUIThread == AfxGetThread())
{
return CDaoRecordset::IsFieldDirty(pv);
}
else
{
pParam1 = pv;
return (BOOL)AfxGetMainWnd()->
SendMessage(WM_MULTIDAOMESSAGE, MultiDaoIsFieldDirty, (LPARAM)this);
}
}
BOOL CMultiDaoRecordSet::IsFieldNull(void* pv)
{
CMYApp *pApp = ((CMYApp *)AfxGetApp());
if (pApp->pGUIThread == AfxGetThread())
{
return CDaoRecordset::IsFieldNull(pv);
}
else
{
pParam1 = pv;
return (BOOL)AfxGetMainWnd()->
SendMessage(WM_MULTIDAOMESSAGE, MultiDaoIsFieldNull, (LPARAM)this);
}
}
BOOL CMultiDaoRecordSet::IsFieldNullable(void* pv)
{
CMYApp *pApp = ((CMYApp *)AfxGetApp());
if (pApp->pGUIThread == AfxGetThread())
{
return CDaoRecordset::IsFieldNullable(pv);
}
else
{
pParam1 = pv;
return (BOOL)AfxGetMainWnd()->
SendMessage(WM_MULTIDAOMESSAGE, MultiDaoIsFieldNullable, (LPARAM)this);
}
}
CString CMultiDaoRecordSet::GetName()
{
CMYApp *pApp = ((CMYApp *)AfxGetApp());
if (pApp->pGUIThread == AfxGetThread())
{
return CDaoRecordset::GetName();
}
else
{
return (CString)*(CString *)AfxGetMainWnd()->
SendMessage(WM_MULTIDAOMESSAGE, MultiDaoGetName, (LPARAM)this);
}
}
short CMultiDaoRecordSet::GetType()
{
CMYApp *pApp = ((CMYApp *)AfxGetApp());
if (pApp->pGUIThread == AfxGetThread())
{
return CDaoRecordset::GetType();
}
else
{
return (short)AfxGetMainWnd()->
SendMessage(WM_MULTIDAOMESSAGE, MultiDaoGetType, (LPARAM)this);
}
}
short CMultiDaoRecordSet::GetEditMode()
{
CMYApp *pApp = ((CMYApp *)AfxGetApp());
if (pApp->pGUIThread == AfxGetThread())
{
return CDaoRecordset::GetEditMode();
}
else
{
return (short)AfxGetMainWnd()->
SendMessage(WM_MULTIDAOMESSAGE, MultiDaoGetEditMode, (LPARAM)this);
}
}
CString CMultiDaoRecordSet::GetSQL()
{
CMYApp *pApp = ((CMYApp *)AfxGetApp());
if (pApp->pGUIThread == AfxGetThread())
{
return CDaoRecordset::GetSQL();
}
else
{
return (CString)*(CString *)AfxGetMainWnd()->
SendMessage(WM_MULTIDAOMESSAGE, MultiDaoGetSQL, (LPARAM)this);
}
}
COleVariant CMultiDaoRecordSet::GetLastModifiedBookmark()
{
CMYApp *pApp = ((CMYApp *)AfxGetApp());
if (pApp->pGUIThread == AfxGetThread())
{
return CDaoRecordset::GetLastModifiedBookmark();
}
else
{
return (COleVariant)AfxGetMainWnd()->
SendMessage(WM_MULTIDAOMESSAGE, MultiDaoGetLastModifiedBookmark, (LPARAM)this);
}
}
long CMultiDaoRecordSet::GetRecordCount()
{
CMYApp *pApp = ((CMYApp *)AfxGetApp());
if (pApp->pGUIThread == AfxGetThread())
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -