2016-11-21 10 views
1

を使用してEventHubにデータを送信すると、ショートバージョン:NullReferenceExceptionが返されます。なぜ接続が切断されていますか?Azure EventHub - NullReferenceExceptionでEventHubClient.Send()が発生する

長い説明:

私はC#でEventHubClientクラスからSendBatchメソッドを使用して、EventHubにデータを送信しようとしています。 (https://docs.microsoft.com/en-us/dotnet/api/microsoft.servicebus.messaging.eventhubclient

バッチサイズは100個のjsonオブジェクトであり、大きすぎてはいけません。私は、より大きなバッチサイズと小さなバッチサイズの両方で同じ問題に遭遇しました。私もSend()を使って、オブジェクトを1つずつ送信しようとしました。同じ結果。

これは時間の偉大な99%に動作しますが、時には、次のスタックトレース残し、NullReferenceExceptionになり:私は両方 EventHubClient.RetryPolicy = RetryPolicy.Default;を使用して、手動で実行して、再試行ポリシーを実装しようとした

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) 

を再接続のために接続時間を与えるために、Thread.Sleep(n)の再帰的メソッド呼び出し。

時々接続は10秒後、時には60秒後に戻ってくることがあります。通常は決して戻りません(またはメソッドの再帰呼び出しがStackOverflowExceptionになるまで約30分後ですが、スレッドが置かれる時間睡眠)。論理的には、私はこのシステムの不安定な部分を持つことはできません。

この例外が発生する理由は誰でも知っていますが、それは接続が切断されたためですか?

答えて

0

ここでの答えは、オーバーロードされた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) 
} 
} 
関連する問題