FC2ブログ

気になるとワスレルナ

見て、聞いて、忘れるループ…けど、忘れちゃいけないことも。メモして独り言。

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

スレッドプログラミング AutoResetEvent

マルチスレッド処理を実装するケースは多々ありますが、スレッドの処理を繰り返し実行したい場合に(毎回スレッドをNewするのではなく)スレッドを使いまわしたいことがあります。
非常に短い間隔で連続して(且つ長時間)スレッド処理を繰り返す場合など、毎回Newすることが重く感じられるためです。

このようなケースで、.NETFramework1.1当時はThreadクラスのSuspend・Resumeメソッドを使っていました。
イメージは↓こんな感じ。
スレッドをキックするメソッド()
{
Resume(スレッドの再開)
}

スレッド処理()
{
whileループ
{
if(条件式)
{
スレッド処理
} else {
Suspend(一時停止)
}
}
}

こうすると、1回の処理が終わる度にスレッドを一時停止状態にしておき、
Resume呼び出しで同じスレッドを再開させる、といったことができるようになります。


しかし、Visual Studio 2005以降でSuspend・Resumeを使用するとコンパイル時に警告が出力され、「使用するな」と怒られてしまいます。
実際には、警告を無視して動作させることもできるようですが、AutoResetEventで代替えできるようなので方法をメモしておきたいと思います。


AutoResetEventクラスは、WaitHandleクラスから派生したクラスです。
WaitHandleクラスのオブジェクトは「待機ハンドル」と呼ばれ、通常はスレッド間の同期に利用されます。

「待機ハンドル」には「シグナル状態」と「非シグナル状態」の2つのステータスがあり、
「待機ハンドル」がどのスレッドからも利用されていない状態を「シグナル状態」、
いずれかのスレッドに利用されていれば「非シグナル状態」となるようです。

そして、WaitOneメソッドを使用すると「待機ハンドル」が「シグナル状態」になるまで、コードの実行を停止させることができます。

ということで、Suspendの代わりにAutoResetEvent.WaitOneメソッド(これで非シグナル状態)を使用してスレッドを停止させ、その後Resumeの代わりにAutoResetEvent.Setメソッド(これでシグナル状態)でスレッドを再開します。

コードのサンプルは↓こんな感じです。
public class ThreadSmaple
{
private bool fsuspend = false;
private AutoResetEvent m_autoev;
private Thread m_thread;

/* コンストラクタ */
public ThreadSmaple()
{
/* 非シグナル状態でAutoResetEventオブジェクトを生成 */
this.m_autoev = new AutoResetEvent(false);

/* スレッドの生成と開始 */
this.m_thread = new Thread(new
ThreadStart(this.threadMe));
this.m_thread.Start();
}

/* 別スレッドで動作する関数 */
public void threadMe()
{
/* 無限ループ */
while(true)
{
if(fsuspend != true)
{
/*
*ここにスレッドで実行したい処理を記述します
*
*/

/* 処理が終わったら次回のループで
一時停止するようにフラグを立てます */
fsuspend = true;
} else {

/* AutoResetEventオブジェクトを
非シグナル状態にしてスレッドを停止させます */
this.m_autoev.WaitOne();
}
}
}

/* スレッドを再開させる関数 */
public void ReStartThread()
{
if (this.m_thread.ThreadState ==
System.Threading.ThreadState.WaitSleepJoin)
{
/* スレッド処理を実行するようにフラグを落とします */
fsuspend = false;

/* AutoResetEventオブジェクトをシグナル状態にして
スレッドを再開させます */
this.m_autoev.Set();
} else {
}
}
}

もちろん、これだけでは、アプリケーション終了時にスレッドを閉じることができないなど色々問題がありますので、システムに組み込む場合には工夫が必要です。
ご注意を。

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://kiniruna.blog.fc2.com/tb.php/14-e2a4857b
この記事にトラックバックする(FC2ブログユーザー)

FC2Ad

FC2ブログ