C# AutoResteEvent在多线程UCMA 3.0应用程序中导致死锁

C# AutoResteEvent在多线程UCMA 3.0应用程序中导致死锁,c#,multithreading,autoresetevent,ucma,C#,Multithreading,Autoresetevent,Ucma,在我的并行中,我正在调用Foreach循环 _helper.subscribeUserEndPoint(loop._contactGrpSvcs); _helper是UserEndPoint和所有其他操作(如Subscribes)的封装类 订阅方法包括: public void subscribeUserEndPoint(ContactGroupServices cntGrpSvcs) { cntGrpSvc

在我的并行中,我正在调用Foreach循环

              _helper.subscribeUserEndPoint(loop._contactGrpSvcs);
_helper是UserEndPoint和所有其他操作(如Subscribes)的封装类

订阅方法包括:

        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();

    }
线程在等待_contactsubscribebcompleted.WaitOne()时死锁;有什么方法可以避免这种死锁争用

干杯

  -- Brian

PS:死锁可能发生的一个原因是由于AutoResetEvent的固有问题--从文档中--“不能保证每次调用Set方法都会释放一个线程。如果两个调用靠得太近,以至于第二个调用发生在释放线程之前,则只释放一个线程。就好像第二次呼叫没有发生一样。此外,如果在没有线程等待的情况下调用Set,并且已经发出了AutoResetEvent的信号,则调用无效。“是否有解决方法?”

通过调用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());
  }   
}

这不是死锁。当两个线程需要访问另一个线程锁定的资源时,就会发生死锁。这里不是这种情况,是什么让你认为这是一个死锁而不仅仅是一个块?要理解死锁,我们需要理解两个线程之间的交互。我看不到死锁的方法,因为
TerminateSubscribe
从不尝试获取竞争锁。对TerminateSubscribe的调用在哪里?BeginSubscribe是否调用过TerminateSubscribe?正如Marc指出的,很有可能它只是一个块,因为两个线程之间的自动resetEvent集彼此接近,然后进入一个线程的WaitOne,而第二个线程仍在等待这里有一个等待句柄,您不能只执行
cntGrpSvcs.EndSubscribe(cntGrpSvcs.BeginSubscribe(null,null))
?(加上一些异常处理/日志记录)