An OperationCanceledException
异常通常意味着事件中心服务操作超时。在您的堆栈跟踪中,客户端在尝试建立到服务的 AMQP 链接并发送授权令牌时似乎超时。
这通常表明服务的网络通信存在问题。如果没有更多关于代码运行环境的上下文,我只能推测原因。
一种常见情况是在无法使用原始 TCP 通信的环境(例如 Xamarin Android)中运行时。另一种常见情况是在防火墙规则过滤传出连接的环境中运行时。对于 TCP 传输,您需要确保标准 AMQP 端口 5671 和 5672 已打开并且可用于传出连接。
要解决这两种情况,您可能需要尝试设置TransportType https://learn.microsoft.com/en-us/dotnet/api/azure.messaging.eventhubs.eventhubconnectionoptions.transporttype?view=azur-dotnet#Azure_Messaging_EventHubs_EventHubConnectionOptions_TransportType在你的EventHubProducerClientOptions https://learn.microsoft.com/en-us/dotnet/api/azure.messaging.eventhubs.producer.eventhubproducerclientoptions?view=azure-dotnet to EventHubsTransportType.AmqpWebSockets
.
例如:
var options = new EventHubClientOptions();
options.ConnectionOptions.TransportType = EventHubsTransportType.AmqpWebSockets;
await using var producer = new EventHubProducerClient(
"<< CONNECTION STRING >>",
"<< EVENT HUB NAME >>",
options);
// MORE CODE...
关于您的代码片段,我想提及的一件重要的事情是您可能会丢失数据。因为你忽略了返回值TryAdd
,如果您传递的枚举大于单批中可以发送的枚举,则您将无法添加它们。
我建议您要么考虑尊重来自的回报TryAdd
或使用SendAsync
接受一组事件的重载。在前面的情况下,如果TryAdd
回报false
,那么您就知道该批次已满,您应该将您的集合分成多个批次。在后一种情况下,如果集合太大而无法在单次调用中发送,则调用将失败。
对于一些额外的想法:
-
我不明白为什么您需要创建取消令牌,因为您没有使用它来请求取消发送,因此您可以跳过该步骤。
-
生产者客户为了方便起见允许处置;像HttpClient
,作为长期客户端使用是有效的。如果您要在一段时间内发送数据,我建议您创建一次,然后仅在您的应用程序关闭或完成发送一段时间后才关闭/处置。
-
The EventDataBatch
是一次性的,并且确实包含对非托管项目的引用。我建议您确保在发送操作完成后对其进行处理。
将一些反馈付诸行动,同时将生产者的范围限制为单个方法调用,示例如下所示:
public async void Send<T>(IEnumerable<T> data, string eventHubName)
{
var options = new EventHubClientOptions();
options.ConnectionOptions.TransportType = EventHubsTransportType.AmqpWebSockets;
await using var producer = new EventHubProducerClient(
this._connectionString,
eventHubName,
options);
try
{
var eventSet =
data.Select(item => new EventData(Encoding.UTF8.GetBytes(item.ToString()));
await producer.SendAsync(eventSet).ConfigureAwait(false);
}
catch (Exception ex)
{
Log($"Error While sending message to Event Hub: { ex.Message}", ex);
throw;
}
}
有关更全面的示例,您可能需要查看:
-
用于创建具有自定义选项的客户端的事件中心示例 https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/eventhub/Azure.Messaging.EventHubs/samples/Sample02_ClientWithCustomOptions.cs
-
用于发布多个批次的事件中心示例 https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/eventhub/Azure.Messaging.EventHubs/samples/Sample04_PublishMultipleEventBatches.cs