![]() | Programming Guide | WideStudio/MWT Index 目次 |
ロックによるスレッドクラスとワーキングダイアログによる長時間の処理の実行
スレッドクラスとワーキングダイアログによる長時間の処理の実行
WSCvthread クラスと WSCworkingDialog を利用すると、 処理時間の長い処理を実行中に描画を止めることなく行なうことができます。
ここでは簡単な例を示しながら、メインスレッドをロックしながらによる スレッドとワーキングダイアログの実装方法に関して説明を行ないます。 プッシュボタンを押下すると、 時間のかかる処理をサブスレッド上で実行し、ワーキングダイアログを 表示するようなアプリケーションを作成します。
まず、ウィンドウをひとつ用意し、プッシュボタンを配置し、 そして、WSCworkingDialog と WSCvthread クラスのインスタンスを それぞれ配置し、名称をそれぞれ、newwork_001、newvthr_002 とします。
プッシュボタンに次のようなイベントプロシージャ btnop() を設定し、 時間のかかる処理をサブスレッド上で実行し、ワーキングダイアログを 表示します。プログラム中に、存在するフラグ dialog_vis_status は、 ワーキングダイアログの popup() メソッドによる表示が終了したことを 処理中のサブスレッドに伝えるためのものです。 ワーキングダイアログがキャンセルされた場合など、popup() が復帰した後、 フラグを False に設定することで、 サブスレッドにおいてワーキングダイアログが非表示状態になったことが解ります。#include <WScom.h> #include <WSCfunctionList.h> #include <WSCbase.h> //---------------------------------------------------------- //Function for the event procedure //---------------------------------------------------------- #include <newwin000.h> //ワーキングダイアログが表示されているかどうかを示すフラグ WSCbool dialog_vis_status = False; void btnop(WSCbase* object){ //do something... dialog_vis_status = True; //スレッドを生成する前にフラグをたてる //スレッドを生成し、処理を実行する。 newvthr_002->executeThread(); //ダイアログを表示状態にする。 newwork_001->popup(); //(注意)ダイアログが非表示状態になるまで復帰せず。 dialog_vis_status = False; } static WSCfunctionRegister op("btnop",(void*)btnop);次に、WSCvthread クラスのインスタンス newvthr_002 に対して、 サブスレッドとして実行する処理を記述したイベントプロシージャを THREAD-STARTED トリガで設定します。 ワーキングダイアログ等でいつでもキャンセルできるようにするため、 サブスレッドとして実行するイベントプロシージャの記述で重要な点のひとつは、 長時間かかる処理をみじかく区切って一定量づつ処理を実行する点です。 下記に示す例は、長い処理全体を 100 回に区切って実行し、 変数 cnt でカウントします。 そして、そのカウントをそのままワーキングダイアログの進み具合の表示に 利用しています。 インスタンスは基本的にスレッドアンセーフなため、 ワーキングダイアログの表示に対して カウンタ値を反映させるために、 WSGIappDev()->lock() を実行し、メインスレッドをロックして ダイアログにアクセスするようにします。#include <WScom.h> #include <WSCfunctionList.h> #include <WSCbase.h> #include <unistd.h> //---------------------------------------------------------- //Function for the event procedure //---------------------------------------------------------- #include <newwin000.h> extern long cnt; extern WSCbool dialog_vis_status; void thread_proc(WSCbase* object){ cnt=0; while(1){ //処理の進み具合をしめすカウンタをカウントアップします。 cnt++; //カウンタの値をワーキングダイアログに反映させるため、 //メインスレッドをロックして //メインスレッド上のワーキングダイアログにアクセス。 WSGIappDev()->lock(); //進み具合をしめすカウンタ値をプロパティに設定します。 newwork_001->setProperty(WSNvalue,cnt); //カウンタ値が 100 以上となった場合、ダイアログを非表示とし、 //処理の終了とします。 if (cnt>100){ newwork_001->setVisible(False); } //メインスレッドのロックを解除する。 WSGIappDev()->unlock(); if (dialog_vis_status == False){ //ダイアログが非表示すなわちキャンセルされたならば処理を終了します。 return; } if (cnt > 100){ //みじかく区切った処理を100回行なったならば処理を終了します。 return; } //ここで長時間かかる処理をみじかく区切って一定量づつ実行します。 #ifdef MSW Sleep(1000); #else sleep(1); #endif } } static WSCfunctionRegister op("thread_proc",(void*)thread_proc);ロースレッドクラスとワーキングダイアログによる長時間の処理の実行
WSDthread クラスと WSCworkingDialog を利用した、 処理時間の長い処理を実行する例を示します。
ウィンドウをひとつ用意し、プッシュボタンを配置します。 そして、WSCworkingDialog クラスのインスタンスを配置し、名称を newwork_000 とします。
プッシュボタンに次のようなイベントプロシージャ btnop() を設定し、 時間のかかる処理をサブスレッド上で実行し、ワーキングダイアログを 表示します。
存在するフラグ canceled を使用した、 自発的にサブスレッドをキャンセルする方法、 WSDthread::terminateThread() メソッドを 利用した強制的にサブスレッドの停止する方法を示します。 WSDthread::terminateThread() メソッドによるサブスレッドの停止は、 処理途中で強制的に停止させられるため、ファイル資源の操作等の 資源操作処理には向きません。
サブスレッドを強制終了する例です。
#include <WScom.h> #include <WSCfunctionList.h> #include <WSCbase.h> #include <WSDthread.h> #include <stdlib.h> #include <unistd.h> //---------------------------------------------------------- //Function for the event procedure //---------------------------------------------------------- #include <newwin000.h> WSDthread* thr = NULL; WSCbool canceled = False; //サブスレッドとして動作するプロシージャ void* thread_func(WSDthread* obj,void*){ //カウンタ long cnt= 0; while(1){ //処理の進み具合をしめすカウンタをカウントアップします。 cnt++; //カウンタの値をワーキングダイアログに反映させるため、 //メインスレッドをロックし //メインスレッド上のワーキングダイアログにアクセスします。 WSGIappDev()->lock(); //進み具合をしめすカウンタ値をプロパティに設定します。 newwork_001->setProperty(WSNvalue,cnt); //カウンタ値が 100 以上となった場合、ダイアログを非表示とし、 //処理の終了とします。 if (cnt>100){ newwork_001->setVisible(False); } //メインスレッドのロックを解除する。 WSGIappDev()->unlock(); //ここで長時間かかる処理をみじかく区切って一定量づつ実行します。 #ifdef MSW Sleep(1000); #else sleep(1); #endif //カウンタが100になった場合、処理を終了します。 if (cnt == 100){ return NULL; } } return NULL; } //ボタン押下により、ワーキングダイアログを表示し、処理を開始。 void btnop(WSCbase* object){ if (thr == NULL){ //スレッドインスタンスを生成。 thr = WSDthread::getNewInstance(); //サブスレッドとして実行するプロシージャを設定 thr->setFunction(thread_func); //サブスレッドを生成 thr->createThread(NULL); //ワーキングダイアログを表示 long val = newwork_000->popup(); if (val == WS_DIALOG_OK){ }else{ //サブスレッドを強制終了する場合。 thr->terminateThread(); } }else{ exit(0); } } static WSCfunctionRegister op("btnop",(void*)btnop);サブスレッドをフラグを参照して安全に終了する例です。
#include <WScom.h> #include <WSCfunctionList.h> #include <WSCbase.h> #include <WSDthread.h> #include <stdlib.h> #include <unistd.h> //---------------------------------------------------------- //Function for the event procedure //---------------------------------------------------------- #include <newwin000.h> WSDthread* thr = NULL; WSCbool canceled = False; //サブスレッドとして動作するプロシージャ void* thread_func(WSDthread* obj,void*){ //カウンタ long cnt= 0; while(1){ //処理の進み具合をしめすカウンタをカウントアップします。 cnt++; //カウンタの値をワーキングダイアログに反映させるため、 //メインスレッドをロックし //メインスレッド上のワーキングダイアログにアクセスします。 WSGIappDev()->lock(); //進み具合をしめすカウンタ値をプロパティに設定します。 newwork_001->setProperty(WSNvalue,cnt); //カウンタ値が 100 以上となった場合、ダイアログを非表示とし、 //処理の終了とします。 if (cnt>100){ newwork_001->setVisible(False); } //メインスレッドのロックを解除する。 WSGIappDev()->unlock(); //ここで長時間かかる処理をみじかく区切って一定量づつ実行します。 #ifdef MSW Sleep(1000); #else sleep(1); #endif //カウンタが100になった場合、処理を終了します。 if (cnt == 100){ return NULL; } //フラグを参照し、処理を中断すべきかを判断します。 if (canceled != False){ return NULL; } } return NULL; } //ボタン押下により、ワーキングダイアログを表示し、処理を開始。 void btnop(WSCbase* object){ if (thr == NULL){ //スレッドインスタンスを生成。 thr = WSDthread::getNewInstance(); //サブスレッドとして実行するプロシージャを設定 thr->setFunction(thread_func); //サブスレッドを生成 thr->createThread(NULL); //ワーキングダイアログを表示 long val = newwork_000->popup(); if (val == WS_DIALOG_OK){ }else{ //サブスレッドに処理を中止させます。 canceled = True; } }else{ exit(0); } } static WSCfunctionRegister op("btnop",(void*)btnop);
Copyright(C) WideStudio/MWT Development Team, 1999-2005 | Last modified: Jul 31, 2005 |