- PR -

別スレッドからのコールバックの結果を安全に呼出元に渡すには?

1
投稿者投稿内容
がらす
ベテラン
会議室デビュー日: 2005/07/14
投稿数: 99
投稿日時: 2005-09-02 04:55
いつもお世話になっています。
今までは1つの関数で行っていた処理を、他と共通のサーバを使って実現するように変更することになりました。今までは単純にシングルスレッドで結果を関数の戻り値として返していたのですが、新しいサーバでは、リクエストとは別スレッドを作って、結果はイベントで知らせてきます。今あるAPIの仕様を変更するわけにもいかないので、イベントで戻ってきた結果を元の関数から渡す必要があります。以下のような方法でとりあえず実現は出来そうなのですが、自分でやりながらかなり気持ちが悪いです。

なにかもっと良い方法は無いでしょうか。よろしくお願いします。

// 結果受渡しのためだけに作成
private ResultType m_result;

ResultType ProcessCalc()
{
m_result = null;
ResultType result = new ResultType();
// 処理後のコールバックが CompletedCallback に来る
CalcClass.CompleteEvent = new ComepleteEventHandler(CompletedCallback);
// このメソッド内で、別スレッドを作って処理を行う(この中身は変更不可)。終了後コールバックが起こる
CalcClass.Process();

// 処理終了まで待機
Monitor.Enter(this);
Monitor.Wait(this, 5000);
result = m_result;
Monitor.Exit(this);

return result;
}

void CompletedCallback(object sender, ResultEventArgs e)
{
Monitor.Enter(this);
m_result = e.Result; //結果を保存
Monitor.Pulse(this);
Monitor.Exit(this);
}
甕星
ぬし
会議室デビュー日: 2003/03/07
投稿数: 1185
お住まい・勤務地: 湖の見える丘の上
投稿日時: 2005-09-04 09:57
ProcessCalc内のMonitor.Enter(this)と、CompletedCallback内のMonitor.Enter(this)がデッドロックを起こしませんか?書き換える変数がm_resultだけなら、クリティカルセクションを設ける必要は無いはずです。

また、この実装では運が悪いとPulseを受け取りそびれる事になりますね。Monitor.Waitを呼び出す前に、CompletedCallbackが呼ばれるとデッドロックするでしょう。

これを踏まえて修正すると、↓な感じ
コード:

// 結果受渡しのためだけに作成
private ResultType m_result;
private ManualResetEvent callbackEvent;

ResultType ProcessCalc()
{
m_result = null;
ResultType result = new ResultType();
// 処理後のコールバックが CompletedCallback に来る
CalcClass.CompleteEvent = new ComepleteEventHandler(CompletedCallback);
// このメソッド内で、別スレッドを作って処理を行う(この中身は変更不可)。終了 後コールバックが起こる
CalcClass.Process();

// 処理終了まで待機
callbackEvent.WaitOne(5000, false);
callbackEvent.Reset();
result = m_result;
return result;
}

void CompletedCallback(object sender, ResultEventArgs e)
{
m_result = e.Result; //結果を保存
callbackEvent.Set();
}


この実装ではスレッドセーフではありません。スレッドセーフにしたいなら、ProcessCalc関数内の処理をクリティカルセクションにしてください。


_________________
甕星 <mikahosi@abox9.so-net.ne.jp>
http://blogs.msmvp.jp/mikahosi/

[ メッセージ編集済み 編集者: 甕星 編集日時 2005-09-04 09:58 ]
1

スキルアップ/キャリアアップ(JOB@IT)