SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Windowsアプリケーションで「処理中」を表現する

時間のかかる処理で「処理中」を表現する(後編)

Windowsアプリケーションで処理中を表現する様々な方法

  • X ポスト
  • このエントリーをはてなブックマークに追加

ダウンロード WaitSample_2.zip (137.4 KB)

 まずは、何もせずに純粋にスレッドの終了を待つサンプルを3つ用意しました。1つは最初のものを待機するように修正したものです。こちらは本当に待機せずという場合に、待機部分を必要なタイミングに持ち越すことでその時に待つことができるようになります。うまく活用すればかなり強力な仕組みが用意できます。

体験スレッド編 - 終了待機1
#include <process.h>
void ThreadBusyLoopEx( DWORD dwTime )
{
  unsigned thrdaddr;
  HANDLE hThread = reinterpret_cast<HANDLE>( _beginthreadex( NULL, 0,
    BusyLoopThProcEx, &dwTime, 0, &thrdaddr ) );
  if( hThread != NULL ){
    // hTread をどこかに保持しておき、プログラム終了時に下記の処理を行えば、中途半端な状態で終わることはなくなる。
    CSimpleWaitCursor  wait;
    WaitForSingleObject( hThread, INFINITE );
    CloseHandle( hThread );
  }
}

 残り2つは、マルチスレッドサンプルでよく見る_beginthread版と、Visual Studio 2010で追加された同時実行ランタイムにある、軽量タスクというスレッドの簡素版を使った例です。どちらも呼び出し部分を相互に入れ替えて使うことができます。

 最後の並列処理部分で改めて出てきますが、同時実行ランタイムを利用する場合は、軽量タスクの利用も検討してみてください。

体験スレッド編 - 終了待機2
#include <process.h>
class CThreadParam
{
public:
  CThreadParam( DWORD dwTime )
    :  m_workTime( dwTime )
    ,  m_event( CreateEvent( NULL, TRUE, FALSE, NULL ) )
  {
  }
  ~CThreadParam()
  {
    if( m_event != NULL ){
      CloseHandle( m_event );
    }
    m_event = NULL;
  }
public:
  DWORD  m_workTime;
  HANDLE  m_event;
};
void _cdecl BusyLoopThProc( void* param )
{
  CThreadParam* pParam = static_cast( param );

  DWORD dwStart = GetTickCount();
  while( (GetTickCount()-dwStart) < pParam->m_workTime );

  SetEvent( pParam->m_event );
}
void ThreadBusyLoop( DWORD dwTime )
{
  CThreadParam  param( dwTime );
  if( param.m_event != NULL ){
    uintptr_t nResult = _beginthread( BusyLoopThProc, 0, &param );
    if( nResult != -1 ){
      CSimpleWaitCursor  wait;
      WaitForSingleObject( param.m_event, INFINITE );
    }
  }
}
体験スレッド編 - 終了待機3
#include <ppl.h>
class CThreadParamPPL
{
public:
  CThreadParamPPL( DWORD dwTime )
    :  m_workTime( dwTime )
  {
    m_event.reset();
  }
public:
  DWORD  m_workTime;
  Concurrency::event  m_event;
};
void _cdecl BusyLoopThProcPPL( void* param )
{
  CThreadParamPPL* pParam = static_cast( param );

  DWORD dwStart = GetTickCount();
  while( (GetTickCount()-dwStart) < pParam->m_workTime );

  pParam->m_event.set();
}
void ThreadBusyLoopPPL( DWORD dwTime )
{
  CThreadParamPPL  param( dwTime );
  CSimpleWaitCursor  wait;
  Concurrency::CurrentScheduler::ScheduleTask( BusyLoopThProcPPL, &param );
  param.m_event.wait();
}
同時実行ランタイムのメモリーリーク

 並列処理を簡素に導入できる同時実行ランタイムですが、現在メモリーリークするという不具合を抱えています。

 もし、この記事を見て早く直した方がいいと思う人がいたら、上記リンクより、重要であると投票をお願いします。また、再現サンプルを利用するなどで再現できるという場合は、再現できたという部分にも投票してもらえると、MSも需要が高いとみなし優先的に修正対象にしてくれると思います。

次のページ
モードレスダイアログを使って終了を待つ

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
Windowsアプリケーションで「処理中」を表現する連載記事一覧
この記事の著者

とっちゃん(トッチャン)

Microsoft MVP for Development Tools Visual C++Windows Installer 系を中心にオンライン/オフラインで活動しています。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/5352 2010/08/05 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング