简短版本:使用 EventHubClient.SendBatch
向 EventHub 发送数据时 NullReferenceException
。为什么连接会被断开?
更长的解释:
我尝试使用 C# 中 EventHubClient
类中的 SendBatch
方法将数据发送到 EventHub
。 ( https://learn.microsoft.com/en-us/dotnet/api/microsoft.servicebus.messaging.eventhubclient )
批量大小为 100 个 json 对象,不宜太大。我在更大和更小的批量大小上都遇到了同样的问题。我还尝试使用 Send()
来一一发送对象。相同的结果。
这在 99% 的情况下都有效,但有时会导致 NullReferenceException
,留下以下堆栈跟踪:
System.NullReferenceException: Object reference not set to an instance of an object.
at Microsoft.ServiceBus.Messaging.MessageSender.RetrySenderEventDataAsyncResu
lt.<>c.<.ctor>b__5_0(EventData e)
at System.Linq.Enumerable.Any[TSource](IEnumerable`1 source, Func`2 predicate
)
at Microsoft.ServiceBus.Messaging.MessageSender.RetrySenderEventDataAsyncResu
lt..ctor(MessageSender sender, TrackingContext trackingContext, IEnumerable`1 me
ssages, TimeSpan timeout, AsyncCallback callback, Object state)
at Microsoft.ServiceBus.Messaging.MessageSender.BeginSendEventData(TrackingCo
ntext trackingContext, IEnumerable`1 eventDatas, TimeSpan timeout, AsyncCallback
callback, Object state)
at Microsoft.ServiceBus.Messaging.EventHubClient.SendBatch(IEnumerable`1 even
tDataList)
我尝试实现重试策略,均使用
EventHubClient.RetryPolicy = RetryPolicy.Default;
并使用 Thread.Sleep(n)
手动执行递归方法调用,为连接提供重新建立的时间。
有时连接会在 10 秒后恢复,有时在 60 秒后恢复,通常不会(或者直到我对该方法的递归调用遇到 StackOverflowException
,大约 30 分钟后,但取决于如何恢复)线程处于休眠状态的时间长)。从逻辑上讲,我不能拥有系统中这个不稳定的部分。
任何人都知道为什么会发生此异常,以及是否是由于连接丢失造成的?
最佳答案
这里的答案是一个重载的EventHub。
对于每 100 个批处理,等待 0.5 秒。对于每个 NullReferenceException,请等待 2 秒,然后再使用相同的数据重试。连接恢复之前可能需要重试 100 次以上。我尝试使用指数等待时间,但在我的情况下并不成功(最终等待了几个小时,但仍然没有连接)。
当然 - 在 C#
中使用永恒的 while 循环而不是递归调用。这可以防止 StackOverflowException。 (菜鸟错误)。
工作代码:
public bool SendMessageAsList(List<EventData list)
{
while(true)
{
var batchList = new List<EventData>();
for (var i = 0; i < list.Count; i + 100)
try
{
if (i % 10000)
Thread.Sleep(500);
batchList = list.Skip(i).Take(100).ToList();
EventHubClient.SendBatch(batchList);
// Gets here at success
list = list.Skip(100).ToList();
if (batchList.Count < 100)
break;
}
catch (NullReferanceException e)
{
Console.WriteLine(e);
Thread.Sleep(2000)
}
}
关于c# - Azure EventHub - EventHubClient.Send() 导致 NullReferenceException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40721723/