0

マルチスレッド環境でプリエンプティブな排他的関数を実装しています。関数が実行されていないときでもキャンセル要求が発生すると、関数が実行されたときに、このキャンセル要求が認識され、実行されません。ManualResetEvent などを使用して C# でこれを行うさまざまな方法に出くわしました (この質問への回答のようなもの停止時に Timers.Timer の経過したメソッドを同期する)、しかし、私がやっているのと同じくらい簡単なものかどうか疑問に思っていました以下のコードで十分です。ここで紹介している不注意なバグはありますか?

bool cancel = false;
bool running = false;
object Lock = new object();
void PremptiveExclusiveFunction() {
  lock(Lock) {
    if(running)
      return;
    running = true;
  }

  for(int i=0; i < numIter; i++) {
    lock(Lock) {
      if(cancel) {
       cancel = false;
       running = false;
       return;
      }
    }

    // iteration code
  }

  lock(Lock) {
   running = false;
  } 
}

void Stop() {
  lock(Lock) {
    cancel = true;
  }
}

私の知る限り、これは私の 3 つの要件を処理している よう です



本当に何かが足りない場合は、より経験豊富な心が指摘していただければ幸いです。

4

1 に答える 1

0

関数本体全体をロックして、runningブール値を排除できます。

object @lock = new object();

volatile bool cancel = false;

void Function () {
    if (!Monitor.TryEnter(@lock))
        return;
    try {

        for (var i = 0; i < 100; i++) {
            if (cancel) {
                cancel = false;
                return;
            }

            // code
        }

    } finally {
        Monitor.Exit(@lock);
    }
}

void Stop () {
    cancel = true;
}

+volatileキーワードに注意してください:
http://msdn.microsoft.com/en-us/library/vstudio/x13ttww7(v=vs.100).aspx

于 2013-08-09T06:10:24.570 に答える