1

リソースへの排他的アクセスを提供すると同時に、他のクラスが読み取るロックの状態 (_isWorking) に関する情報を提供する方法を見つけようとしています。

これが私がこれまでに思いついたものです:

    private int _isWorking = 0;

    public bool IsWorking
    {
        get { return Interlocked.CompareExchange(ref _isWorking, 0, 0) == 1; }
    }

    public void LaunchProcess()
    {
        if (Interlocked.CompareExchange(ref _isWorking, 1, 0) == 0)
        {
            try
            {
                DoExpansiveProcess();
            }
            finally
            {
                Interlocked.Exchange(ref _isWorking, 0);
            }
        }
    }

    public void DoExpansiveProcess()
    {
        Thread.Sleep(30000);
    }

2 番目のスレッドは、スレッドが既にプロセスを実行していることを確認すると、メソッドを離れて何もしないため、正確にはロックとして機能しません。

これを行うのは正しい方法ですか、それとも目的により適した C# 3.5 構造はありますか?

そして、状態に関する情報を提供しながら、最初のスレッドが終了した後も2番目のスレッドがメソッドを実行する「実際の」ロックシナリオを実装する方法は?

4

3 に答える 3

1

私があなたの質問を正しく理解していると仮定すると、あなたがMonitor.TryEnter求めているのは、タイムアウト値が 0 のメソッドだと思います。ロックを取得しようとしますが、タイムアウトが 0 の場合、ロックがあったかどうかを示す値で常にすぐに戻ります。実際に取得しました。ここでの意味は、ロックが取得されなかった場合、他の誰かによって既に取得されていると見なされるということです。問題は、返された場合true、 を呼び出してすぐに解放する必要があることMonitor.Exitです。

おそらく、これはより良い解決策になるでしょう:

public class Worker
{
  private Object m_LockObject = new Object();
  private volatile bool m_IsWorking = false;

  public bool IsWorking
  {
    get { return m_IsWorking; }
  }

  public void LaunchProcess()
  {
    lock (m_LockObject)
    {
      m_IsWorking = true;
      DoExpansiveProcess();
      m_IsWorking = false;
    }
  }
}
于 2010-06-24T13:02:57.917 に答える
0

ManualResetEventは基になるアンマネージプリミティブをラップするため、あなたのアプローチは一般的に正しく、ManualResetEventを使用するよりも間違いなくはるかに高速であると思います。

ただし、このアプローチを安全にするには、_isWorkingをプライベートにする必要があります。

于 2010-06-24T10:13:54.963 に答える
0

System.Threading.ManualResetEventここで役立つかもしれません。それに対して WaitOne() を実行するだけです。使用されている場合は、false として返されます。使用していない場合は使用可能です。

WaitOne() オーバーロードの 1 つは、待機にミリ秒単位の時間がかかります。WaitOne(0) を使用すると、待機はブロックされない方法ですぐに戻ります。

.Net が提供する同期プリミティブについて調査する必要があります。

System.Threading.Monitor lock() { }
System.Threading.ManualResetEvent
System.Threading.AutoResetEvent
System.Threading.Semaphore
System.Threading.Mutex
于 2010-06-24T09:56:53.110 に答える