1

今日、次のような C# コードを見つけました。

lock(obj)
{
  //  perform various operations
  ...

  //  send a message via a queue but in the same process, Post(yourData, callback)
  messagingBus.Post(data, () => 
  {
    //  perform operation
    ...
    if(condition == true)
    {
      //  perform a long running, out of process operation
      operation.Perform();
    }
  }
}

私の質問はこれです: operation.Perform() が呼び出される前に lock(obj) が解放されないように、コールバック関数を呼び出すことはできますか? つまり、ロックを保持している同じスレッドで、そのスレッドがロックを解放する前に、コールバック関数を呼び出す方法はありますか?

EDIT:messagingBus.Post(...)は、キューへの挿入であると見なすことができ、すぐに戻ります。コールバックは、おそらくスレッド プールから、他のスレッドで呼び出されます。

operation.Perform() については、 Thread.Sleep(10000) として読み取ることができます。これは、長時間実行され、状態を共有または変更しないものです。

4

4 に答える 4

0

推測します。

Post.netでは、通常、作業が別のスレッドによって、または別の時間に行われることを意味します。

そうです、呼び出されるobj前にロックオンが解除される可能性があるだけでなくPerform、それが発生する可能性もかなりあります。ただし、それは保証されません。ロックが解除される前に実行が完了する場合があります。

それが問題だという意味ではありません。「さまざまなアクションを実行する」部分には、ロックが必要な場合があります。MessagingBusは、アクションをキューに入れるためにロックが必要な場合があります。内部の作業ではロックがまったく必要ない場合があります。その場合、コードはスレッドセーフです。

これはすべて推測です。何が行われているのか、なぜそれがロック内になければならないのか、そして何Postを実行するのかという概念がないからです。したがって、コードは完全に安全であるか、ひどく欠陥がある可能性があります。

于 2012-07-19T20:12:39.617 に答える
0

MessageBus.Post がどのように実装されているかを知らずに質問に答えることは不可能です。非同期 API は通常、コールバックが完全に同時に実行されるという保証を提供しません。たとえば、FileStream.BeginRead などの .Net APM メソッドは、オペレーションを同期的に実行することを決定する場合があります。この場合、コールバックは、BeginRead を呼び出した同じスレッドで実行されます。この場合、返された IAsyncResult.CompletedSynchronously は true に設定されます。

于 2012-08-11T15:14:51.893 に答える
0

コールバックが非同期で実行される場合、はい、Post() がそのケースを回避するために特定の何かを行わない限り (これは珍しいことです)、Perform() 時にロックが保持される可能性があります。

コールバックが Post() の呼び出しと同じスレッドでスケジュールされた場合 (たとえば、スレッド プールにスレッドが 1 つしかない極端な例)、スレッド プールの一般的な実装では、スレッドが現在のタスクを終了するまでコールバックを実行しません。この場合、Perform() を実行する前にロックを解除する必要があります。

于 2012-08-11T14:54:14.973 に答える
0

messagesBus.Post が何をしているのかを知らなければ、わかりません。 Post が指定されたデリゲート (例ではラムダ式) を呼び出すと、そのラムダが実行されている間、ロックがかかります。 Post がそのデリゲートを後で実行するようにスケジュールする場合、ラムダの実行中にロック行われません。lock(obj) が何のためにあるのか、messagingBus.Post への呼び出しをロックするのか、それとも何のためにあるのかは明らかではありません。

于 2012-07-19T20:38:59.617 に答える