新聞中心
隨著互聯(lián)網(wǎng)的發(fā)展,數(shù)據(jù)采集成為了企業(yè)獲取信息的重要手段之一。而MFC作為一種經(jīng)典的Windows開發(fā)框架,其內(nèi)置的多線程機制可以很好地處理大規(guī)模數(shù)據(jù)采集的需求。本文將介紹如何使用MFC實現(xiàn)多線程的數(shù)據(jù)庫采集,以及在實踐中需要注意的問題。

創(chuàng)新互聯(lián)公司是一家專業(yè)提供囊謙企業(yè)網(wǎng)站建設(shè),專注與網(wǎng)站建設(shè)、網(wǎng)站設(shè)計、H5場景定制、小程序制作等業(yè)務(wù)。10年已為囊謙眾多企業(yè)、政府機構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站設(shè)計公司優(yōu)惠進行中。
一、多線程的優(yōu)勢
在進行大規(guī)模數(shù)據(jù)采集時,單線程的效率是非常低下的,容易造成資源的浪費和性能的下降。而多線程的優(yōu)勢在于可以將任務(wù)分割成多個子任務(wù),并行地執(zhí)行,從而提高采集的效率,減少時間成本。
MFC提供了多種多線程的支持機制,包括CWinThread、CMultiThread、CTaskThread等,可以根據(jù)實際需求選擇合適的方式。
二、數(shù)據(jù)庫采集的實現(xiàn)過程
以下將介紹一個簡單的數(shù)據(jù)庫采集實現(xiàn)過程,以SQL Server數(shù)據(jù)庫為例。
1. 打開數(shù)據(jù)庫連接
使用AfxDaoInit()函數(shù)初始化ODBC數(shù)據(jù)庫,并打開與SQL Server的連接。如下所示:
CDatabase db;
CString strSQLConnect = _T(“ODBC;Driver={SQL Server};Server=MyServer;Database=MyDatabase”);
db.OpenEx(strSQLConnect);
其中,MyServer表示SQL Server的名稱,MyDatabase表示數(shù)據(jù)庫名稱。
2. 構(gòu)造查詢語句
針對具體的需求,構(gòu)造相應(yīng)的SQL查詢語句,如:
CString strSql = _T(“SELECT * FROM tb_books WHERE book_author LIKE ‘%George%'”);
其中,tb_books為表名,book_author為字段名稱。
3. 執(zhí)行查詢語句
使用CRecordset的Open()函數(shù)執(zhí)行查詢語句,并將結(jié)果保存在結(jié)果集中,如:
CRecordset rs(&db);
rs.Open(CRecordset::forwardOnly, strSql);
其中,forwardOnly表示的是結(jié)果集的模式,表示只能向前遍歷每一條記錄,而不支持任意方向的移動。
4. 處理查詢結(jié)果
利用CRecordset提供的查找、定位、遍歷等方法,處理查詢結(jié)果。例如:
CString strBookName;
while (!rs.IsEOF())
{
rs.GetFieldValue(_T(“book_name”), strBookName);
// 處理查詢結(jié)果,如輸出、保存等操作
rs.MoveNext();
}
其中,GetFieldValue()函數(shù)可以從結(jié)果集中獲取指定字段的值。
三、MFC多線程的實現(xiàn)
以上是基于單線程的數(shù)據(jù)庫查詢操作,接下來將介紹如何利用多線程機制,實現(xiàn)更高效的數(shù)據(jù)采集操作。
1. 創(chuàng)建新的工作線程
在主線程中,創(chuàng)建新的工作線程,并調(diào)用其函數(shù)進行后臺數(shù)據(jù)采集操作。如下所示:
CWinThread* pThread = AfxBeginThread(&MyThreadFunc, NULL);
其中,MyThreadFunc為新線程的執(zhí)行函數(shù)名稱。
2. 實現(xiàn)多線程采集函數(shù)
針對具體的數(shù)據(jù)采集需求,實現(xiàn)多線程的采集函數(shù)。為了能夠在多線程中訪問數(shù)據(jù)庫,需要定義一個全局的數(shù)據(jù)庫對象指針:
CDatabase* g_pDb;
并在新線程啟動后,為其初始化:
g_pDb = new CDatabase;
CString strSQLConnect = _T(“ODBC;Driver={SQL Server};Server=MyServer;Database=MyDatabase”);
g_pDb->OpenEx(strSQLConnect);
在采集函數(shù)中,通過參數(shù)的方式傳入采集需要的參數(shù),并在函數(shù)內(nèi)部調(diào)用數(shù)據(jù)庫查詢操作,如:
UINT MyThreadFunc(LPVOID pParam)
{
// 獲取采集參數(shù)
CString strKeyword = *(CString*)pParam;
// 構(gòu)建查詢語句
CString strSql;
// …
// 執(zhí)行查詢
CRecordset rs(g_pDb);
rs.Open(CRecordset::forwardOnly, strSql);
// 處理結(jié)果
// …
return 0;
}
其中,參數(shù)pParam是一個指向void類型的指針,表示傳入的參數(shù)??梢酝ㄟ^強制類型轉(zhuǎn)換的方式,將其轉(zhuǎn)換為需要的類型。
3. 處理多線程采集結(jié)果
在多線程采集完成后,需要將結(jié)果處理。可以在主線程中,將采集結(jié)果保存在一個全局變量中,并在新線程執(zhí)行完成后,讀取處理。如下所示:
// 全局變量,用于保存采集結(jié)果
vector g_vBooks;
UINT MyThreadFunc(LPVOID pParam)
{
// …
// 處理結(jié)果
CString strBookName;
while (!rs.IsEOF())
{
rs.GetFieldValue(_T(“book_name”), strBookName);
g_vBooks.push_back(strBookName);
rs.MoveNext();
}
return 0;
}
在新線程執(zhí)行結(jié)束后,可以在主線程中遍歷全局變量,完成對采集結(jié)果的處理。
四、注意事項
在實踐中,需要注意以下幾點:
1. 數(shù)據(jù)庫連接和關(guān)閉:在使用完畢后,應(yīng)該及時關(guān)閉數(shù)據(jù)庫連接,釋放資源。
2. 多線程調(diào)用的安全性:不同的線程之間,可能會同時訪問數(shù)據(jù)庫資源,需要注意線程安全性。
3. 任務(wù)的拆分和分配:多線程采集最重要的一點是,如何將任務(wù)拆分,并分配給不同的線程。需要根據(jù)實際情況,靈活選擇。
四、
成都網(wǎng)站建設(shè)公司-創(chuàng)新互聯(lián),建站經(jīng)驗豐富以策略為先導(dǎo)10多年以來專注數(shù)字化網(wǎng)站建設(shè),提供企業(yè)網(wǎng)站建設(shè),高端網(wǎng)站設(shè)計,響應(yīng)式網(wǎng)站制作,設(shè)計師量身打造品牌風(fēng)格,熱線:028-86922220我也有類似的問題需要請教:用MFC進行數(shù)據(jù)庫的一些操作處理。新手,真心求助!
inline _RecordsetPtr Connection15::Execute ( _bstr_t CommandText, VARIANT * RecordsAffected, long Options ) {
struct _Recordset * _result = 0;
HRESULT _hr = raw_Execute(CommandText, RecordsAffected, Options, &_result);
if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
return _RecordsetPtr(_result, false);
}
我的出猜正正現(xiàn)在這個函數(shù),不穗悔知道該怎清明么處理
內(nèi)存錯誤,這個不好說! 你調(diào)試運行,出錯之后程序會停下,你看停在哪的,之后再看什么問題!
關(guān)于MFC中多線程問題
調(diào)整一下編譯選項,選擇多線程動態(tài)庫支持
(CGEDlg*)lpParameter->m_geApplication…
遇到過這種問題,是msvcrt庫升在windows級到sp1后造成的,當(dāng)時我的解決辦法就是靜態(tài)編譯,沒別的方法了。
是哪個庫函數(shù)調(diào)用出錯?
訪問全局變量、讀寫文件,你做了線程之間同步互斥嗎?
可以用MsgWaitForMultipleObjects等待線程完成運算,而且不阻塞消息循環(huán)。
能編譯鏈接通過應(yīng)該跟編譯選項沒關(guān)系了。
但是有個問題:
GetPointOnTerrainFromScreenCoords的VC版本應(yīng)該有3個參數(shù)才對呀,只有2個參數(shù)那是c#和VB的用法。
下面是VC的聲明:
HRESULT GetPointOnTerrainFromScreenCoords ( double screen_x, double screen_y, IPointOnTerrainGE **pPoint)
多線程,計算過程為全局的東西,怎么可能會報錯呢?CreateInstance,然后在ThreadProc響應(yīng),其中的所有變量都是全局的,假如與主線程有共用的變量,用CMutex的Lock,UnLock完全可以同步,使用多線程至今未出錯,請將錯誤提示貼出,我也好學(xué)習(xí)下
怎么在基于對話框的MFC程序中實現(xiàn)多線程?
基于MFC的對話框程序加啟動進度條(轉(zhuǎn))
對于比較大的程序,在啟動的時候都會顯示一個畫面,以告訴用戶程序正在加載,或者顯示一些關(guān)于軟件的信息,如Visual C++,Word, PhotoShop等。
這些啟動畫面在Visual C++中怎么實現(xiàn)呢?對于文檔/視圖結(jié)構(gòu)的程序,可以直接使用VC提供的SplashWnd組件??墒窃诨趯υ捒虻某绦騾s不能使用SplashWnd組件。因此只能自己來實現(xiàn)此功能。
因為顯示啟動畫面的同時還要進行程序的加載工作,所以要用到
多線程
。前尺MFC區(qū)分了兩種不同類型的多線程:
用戶界面
(UI)線程和工作者線程。兩者的區(qū)別是UI線程有消息循環(huán),而工作者線程沒有,UI線程能夠創(chuàng)建窗口并處理發(fā)送給窗口的消息。工作者線程用來執(zhí)行后臺任務(wù),這些后臺任務(wù)不直接接受用戶輸入,因此不需要窗口和消息循環(huán)。 因為這里要顯示一個畫面,所以要使用UI線程。
下面結(jié)合我做的一個小軟件“實用鬧鐘”來說明如何為對話框程序制作啟動畫面。
打開Visual C++建立一個對話框工程Page.
首先準備一副位圖資源插入到工程中,作為啟動時顯示的畫面。再插入一個對話框,設(shè)置ID為IDD_SPLASH。在上面放一個picture控件,類型設(shè)為”慧念高Bitmap”,圖象選擇剛才插入的位圖。
設(shè)置對話框的Style為Popup,Border 為None,去掉Title Bar屬性,并調(diào)整對話框的大小與位圖等大,這樣對話框顯示的時候,你看到的只是圖片。打開 ClassWizard為此對話框建立一個新類CSplashDlg, 基類為CDialog.
UI線程是由一個動態(tài)可創(chuàng)建的類來控制,該類是從CWinThread派生的,非常類似從CWinApp派生的一個
應(yīng)用程序
類.打開ClassWizard建立一個由CWinThread派生的類—-CSplashThread,在SplashThread.h 中加入 #include”SplashDlg.h”,并添加一個protected型指針變量:
CSplashDlg* m_pSplashDlg; //聲明一個對話框指針
下面我們將在UI線程的InitInstance()函數(shù)中調(diào)用剛才創(chuàng)建的對話框并顯示。
BOOL CSplashThread::InitInstance()
{
::AttachThreadInput(m_nThreadID, AfxGetApp()->m_nThreadID, TRUE );
//:通常系統(tǒng)內(nèi)的每個線程都有自己的輸入隊列。本函數(shù)允許線程和進程共享輸入隊列。連接了線程后,輸入焦點、窗口激活、鼠標捕獲、鍵盤狀態(tài)以及輸入隊列狀態(tài)都會進入共享狀態(tài) . (這個函數(shù)可以不用)
m_pSplashDlg=new CSplashDlg;
m_pSplashDlg->SetEnable(true);
m_pSplashDlg->Create(IDD_SPLASH);
m_pSplashDlg->ShowWindow(SW_SHOW);
return true;
}
為CSplashThread類添加一個函數(shù)HideSplash(), 用來隱藏啟動畫面(即關(guān)閉對話框)
void CSplashThread::HideSplash()
{
m_pSplashDlg->SendMessage(WM_CLOSE);
}
在ExitInstance()中釋放資源:
int CSplashThread::ExitInstance()
{
m_pSplashDlg->高豎DestroyWindow();
delete m_pSplashDlg;
return CWinThread::ExitInstance();
}
在應(yīng)用程序類CPageApp中包含
頭文件
: #include “SplashThread.h”
并添加兩個變量:
public://設(shè)為pulic類型,是為了在其他類中能夠訪問
CSplashThread* pSplashThread;
CSplashDlg* m_pSplashDlg;
在InitInstance()中啟動UI線程:
pSplashThread = (CSplashThread*) AfxBeginThread(
RUNTIME_CLASS(CSplashThread),
THREAD_PRIORITY_NORMAL,
0, CREATE_SUSPENDED);
ASSERT(pSplashThread->IsKindOf(RUNTIME_CLASS(CSplashThread)));
pSplashThread->ResumeThread();
Sleep(1);
為了讓程序一起動就顯示啟動畫面,這段代碼應(yīng)該放在InitInstance()最開頭的地方.
啟動畫面是顯示了,可是結(jié)束代碼應(yīng)該放在什么地方呢?如果放在InitInstance()的CPageDlg dlg; m_pMainWnd = &dlg; 后面,即在構(gòu)造了主對話框之后隱藏啟動畫面, 程序運行時會發(fā)現(xiàn),啟動畫面結(jié)束后,還要等一會才能顯示出主對話框,這樣就達不到啟動畫面應(yīng)有的效果. 更好應(yīng)該在即將顯示主對話框的時候隱藏啟動畫面. 我的這個軟件中在主對話框中定義了5個子對話框類的對象,分別是page1,page2,…page5.
程序啟動時的流程如下:
Page1構(gòu)造 —>Page2構(gòu)造 —>Page3構(gòu)造—> Page4構(gòu)造—> Page5構(gòu)造—> 主對話框構(gòu)造 —>主對話框初始化—> Page1初始化—> Page2初始化 —>Page3初始化 Page4初始化—> Page5初始化
由此可見,啟動畫面結(jié)束的更好地方應(yīng)該是在 page5的初始化函數(shù)中
BOOL CPage5::OnInitDialog()
{
CDialog::OnInitDialog();
if ( ((CPageApp*)AfxGetApp())->pSplashThread != NULL)
((CPageApp*)AfxGetApp())->pSplashThread->HideSplash();
return TRUE;
}
到此,一個對話框程序的啟動畫面就這樣完成了.由于是用對話框作為啟動畫面,所以你可以你可以發(fā)揮你的想象力,在對話框上設(shè)計出豐富多才的效果來,比如加上Flash,Gif動畫等.
在將要處理數(shù)據(jù)的地方,使用 AfxBeginThread開創(chuàng)一個線程,AfxBeginThread很簡單是MFC封閉的全局函數(shù),你可以查一下用法,注意過程函數(shù)必須敏舉碧是靜態(tài)的或是全局的。然后將橋舉數(shù)據(jù)通過AfxBeginThread的參數(shù)傳遞給過程函數(shù)去處答銀理。至于計算后的結(jié)果嗎。建議,你使用向主窗口發(fā)MSG的方法通知給主窗口。
MFC線襪旅程創(chuàng)建函數(shù):AfxBeginThreadWin32線程告兄凳創(chuàng)建函數(shù)塵好:CreateThreadCRT線程創(chuàng)建函數(shù):_beginthread / _beginthreadex 這3種方法都可以
寫一個線程函者畢數(shù),參數(shù)與歷嫌饑返回值如下所示
UINT ThreadTest(LPVOID pParam);
然后在按鈕里肢返直接用如下函數(shù)啟動線程
AfxBeginThread(ThreadTest,NULL);
關(guān)于mfc 多線程采集數(shù)據(jù)庫的介紹到此就結(jié)束了,不知道你從中找到你需要的信息了嗎 ?如果你還想了解更多這方面的信息,記得收藏關(guān)注本站。
成都創(chuàng)新互聯(lián)科技公司主營:網(wǎng)站設(shè)計、網(wǎng)站建設(shè)、小程序制作、成都軟件開發(fā)、網(wǎng)頁設(shè)計、微信開發(fā)、成都小程序開發(fā)、網(wǎng)站制作、網(wǎng)站開發(fā)等業(yè)務(wù),是專業(yè)的成都做小程序公司、成都網(wǎng)站建設(shè)公司、成都做網(wǎng)站的公司。創(chuàng)新互聯(lián)公司集小程序制作創(chuàng)意,網(wǎng)站制作策劃,畫冊、網(wǎng)頁、VI設(shè)計,網(wǎng)站、軟件、微信、小程序開發(fā)于一體。
新聞名稱:MFC多線程數(shù)據(jù)庫采集實戰(zhàn)(mfc多線程采集數(shù)據(jù)庫)
分享鏈接:http://fisionsoft.com.cn/article/dhgicij.html


咨詢
建站咨詢
