MFC VC++でスレッド処理
仕事でスレッド処理を追加することになったけども、VC++で経験がなかったので備忘録ついでに書いておきます。
今回の要件は
・メイン処理はOnTimerの中で動く。
・OnTimerは100ミリ秒で動き続ける。
・テキストファイルにログを随時書き込みしたい。
(途中で終了してもログを保存したい。)
・書き出し処理でメイン処理が停止しないようにスレッド化して対応する。
といったところでしょうか。
サンプルとして作成したアプリは次のようなものです。
・OnTimerで現在時刻をエディットボックスに追加していく。
・追加した文字列をテキストファイルに追記する。
まずはメイン処理となるOnTimerのソースから
void CThreadSampleDlg::OnTimer(UINT_PTR nIDEvent)
{
// 現在時刻を取得
SYSTEMTIME systime;
GetSystemTime(&systime);
m_writeStr.Format(_T("%04u/%02u/%02u %02u:%02u:%02u:%03u\r\n"),
systime.wYear, systime.wMonth, systime.wDay,
systime.wHour, systime.wMinute, systime.wSecond,
systime.wMilliseconds);// テキストに描画
m_counter.SetWindowText(m_writeStr);// エディットボックスに追記
int nLen = m_edit.GetWindowTextLength();
m_edit.SetFocus();
m_edit.SetSel(nLen, nLen);
m_edit.ReplaceSel(m_writeStr);// 配列に時刻文字列を追加
m_strArr.push_back(m_writeStr);// スレッド開始
AfxBeginThread(&CThreadSampleDlg::MyThreadProc, (LPVOID)this, THREAD_PRIORITY_IDLE);CDialogEx::OnTimer(nIDEvent);
}
次にスレッド処理部のソース
UINT CThreadSampleDlg::MyThreadProc(LPVOID pParam)
{
CThreadSampleDlg* pThreadSample = (CThreadSampleDlg*)pParam;CStdioFile csFile;
CString cstr;
int err = 0;// ファイルオープン&生成
if (!err) {
if (!csFile.Open(_T("Sample.txt"), CFile::modeWrite | CFile::modeNoTruncate | CFile::shareExclusive | CFile::modeCreate)) {
err = 1;
}
}// 追記処理
if (!err) {
TRY {
// 最終行にポインタを移動
csFile.SeekToEnd();
// 区切り文字列を追記
int logLines = pThreadSample->m_strArr.size();
cstr.Format(_T("----*----*%04u*----*----\r\n"), logLines);
csFile.WriteString(cstr);// 時刻文字列を追記
for (int i = 0; i < logLines; i++) {
CString line = pThreadSample->m_strArr[i];
csFile.WriteString(line);
}
} CATCH (CFileException, eP) {
err = 1;
} END_CATCH
}// ファイルクローズ
csFile.Close();
return 0;
}
念のため、ボタンでOnTimerを停止させる処理を追加してあるんですが、
OnTimerを100ミリ秒で動かしているせいなのかボタンを連打しないと停止してくれません。。。
このあたりはまだまだ調査不足というか知識不足ですね。