EventHubClient.SendBatchAsync - 它是线程安全的吗?

EventHubClient.SendBatchAsync - is it thread-safe?

根据文档,EventHubClient 的所有非静态调用都不是线程安全的。这意味着我无法从任何地方轻松调用以下函数:

    public async Task SendBatchAsync(IList<EventData> eventHubBatch)
    {
        try
        {
            await this.eventHubClient.SendBatchAsync(eventHubBatch);
        }
        catch (Exception ex)
        {
            Console.WriteLine("ERROR (EH WRITER): {0}", ex.Message);
        }
    }

想知道有哪些替代方案?

  1. 锁定
  2. 同步线程上下文
  3. 保存到某个队列并有一个基于线程池的 async/await while 循环,它从队列中读取并进一步发布到 EventHub

更新:Event Hub 团队的 Eric 确认在多线程环境中按原样使用 SendAsync 是安全的。

更新 2:MSDN 文档刚刚更新(2 小时内,哇!)。现在它说:"Any public static or instance members of this type are thread safe.".

Cesar 提供了很好的 Whosebug link 作为答案。为您的特定 (EventHub) 问题补充信息:

  1. 如果您问 "Will my data be corrupted if multiple threads call the API using the same instance" 那么答案是否定的,我们确实保证数据损坏情况下的线程安全。

  2. 如果你问 "Will my data ordering be preserved if multiple threads call the API using the same instance" 那么答案取决于,因为我们确实在接收数据时保持顺序,但是让多个线程调用同一个实例意味着你不能真正确定哪个调用先来到我们的网络实现层。如果您想要订购,请将它们作为单个批次发送 (SendBatchAsync),因为我们确实保证批量订购。请注意,单个批次有大小限制(总共 256k)

您提供的文档 link (https://msdn.microsoft.com/library/azure/microsoft.servicebus.messaging.eventhubclient.aspx) 包含 incomplete/incorrect 信息,我们将返回并根据需要 review/edit。

根据 MSDN EventHubClient documentation 不保证 SendBatchAsync 方法是线程安全的。

话虽这么说,根据我的经验,有相当多的工作人员以多线程方式使用 EventHubClient,我从未遇到过使用该特定方法的线程安全问题。

关于处理这种情况的选项,它与使用任何需要同步的多线程代码没有什么不同。

您可以使用您建议的任何替代方案,此外,您还可以为每个线程创建新的 EventHubClient,因此由于只有一个线程使用它,因此您不会遇到互斥问题。我不知道你的情况,例如这个解决方案对于你生成许多使用 EventHubClient 然后关闭的线程的系统来说不是很好(事件中心连接时间 + 分配问题等)