1

私のParallel.Foreachループで私は呼んでいます

              _helper.subscribeUserEndPoint(loop._contactGrpSvcs);

_helper は、UserEndPoint および購読などの他のすべての操作のカプセル化クラスです。

Subscribe メソッドは次のとおりです。

        public void subscribeUserEndPoint(ContactGroupServices cntGrpSvcs)
        {

            cntGrpSvcs.BeginSubscribe(TerminateSubscribe, cntGrpSvcs);

            _contactSubscribeCompleted.WaitOne();

            LOG.Info("Returning from Successful Subscribe Endpoint");
        }


    private void TerminateSubscribe(IAsyncResult result)
    {

        ContactGroupServices cntGrpSvcs = result.AsyncState as ContactGroupServices;
        try
        {
            cntGrpSvcs.EndSubscribe(result);
        }
        catch (Exception ex)
        {
            LOG.Error("Failed to Complete Subscribe. " + ex.StackTrace);
        }
        CollaborationSubscriptionState state = cntGrpSvcs.CurrentState;
        LOG.Info("Subscribed State = " + state.ToString());

            _contactSubscribeCompleted.Set();

    }

_contactSubscribeCompleted.WaitOne(); の待機中にスレッドがデッドロックする このデッドロック競合を回避する方法は何ですか?

乾杯、

  -- Brian

PS: デッドロックが発生する可能性のある理由の 1 つは、AutoResetEvent に固有の問題があるためです -- ドキュメントから -- 「Set メソッドへのすべての呼び出しがスレッドを解放するという保証はありません。2 つの呼び出しが近すぎる場合、スレッドが解放される前に 2 番目の呼び出しが発生するようにすると、1 つのスレッドのみが解放されます。2 番目の呼び出しが発生しなかったかのようになります。また、待機しているスレッドがなく、AutoResetEvent が既に通知されているときに Set が呼び出されると、 call has no effect. " これに対する回避策はありますか??

4

1 に答える 1

0

begin メソッドを呼び出して操作が完了するのを待つことで、API を完全に同期して呼び出すことができます。これは、waithandle を使用しない方が簡単です。begin メソッドと end メソッドをチェーンするだけです。

public void subscribeUserEndPoint(ContactGroupServices cntGrpSvcs)
{
  try
  {
    cntGrpSvcs.EndSubscribe(cntGrpSvcs.BeginSubscribe(null, null));
    CollaborationSubscriptionState state = cntGrpSvcs.CurrentState;
    LOG.Info("Subscribed State = " + state.ToString());
    LOG.Info("Returning from Successful Subscribe Endpoint");
  }
  catch (Exception ex)
  {
    LOG.Error("Failed to Complete Subscribe. Exception: " + ex.ToString());
  }   
}
于 2012-06-07T00:09:42.493 に答える