自动重置事件导致多线程 UCMA 3.0 应用程序中的死锁

本文关键字:应用程序 死锁 UCMA 多线程 事件 | 更新日期: 2023-09-27 18:36:25

In My Parallel.Foreach Loop 我正在调用

              _helper.subscribeUserEndPoint(loop._contactGrpSvcs);

_helper 是 UserEndPoint 和所有其他操作(如订阅)的封装类

订阅方法包括:

        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:可能发生死锁的一个原因是由于AutoResetEvent的固有问题 - 从文档中 - "不能保证每次调用Set方法都会释放一个线程。如果两个调用靠得太近,以至于第二个调用发生在线程释放之前,则只释放一个线程。就好像第二个电话没有发生一样。此外,如果在没有线程等待时调用 Set,并且已发出自动重置事件信号,则该调用不起作用。" 有解决方法吗?

自动重置事件导致多线程 UCMA 3.0 应用程序中的死锁

通过调用 begin 方法,然后等待操作完成,您将以完全同步的方式调用 api。没有等待手柄更容易做到这一点。您可以将开始和结束方法链接在一起。

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