2016-12-14 13 views
3

キューから読み込んで(独自のスレッドで)1つのアイテムを処理し、キューが空になるまで繰り返すコードブロックがあります。なぜNullReferenceExceptionが発生するのか分かりません

public ActionResult GetOrdersAsync() { 

     int count = 0; 
     SyncDM sync = _common.StartSync(); 

     while (sync != null && sync.SyncId != 0) { 

      int customerId; 
      bool result = int.TryParse(sync.Payload, out customerId); 
      if (result) { 
       Task.Run(() => GetOrders(sync.SyncId, customerId)); 
      } 

      count++; 
      //Process the next Sync 
      sync = _common.StartSync(); 

     } 

     return Json(new JsonModel { 
      Message = "Started " + count + " instances of GetOrders", 
      Success = count > 0 
     }); 

    } 

StartSync()は、キューからアイテムを削除するか、キューが空の場合はnullを返します。 GetOrders()はオブジェクトを処理します。

問題はこのコードでNullReferenceExceptionが発生することがあります。 Task.Run(()=> GetOrders(sync.SyncId、customerId));

デバッガでは、同期はnull(例外の理由)ですが、customerIdには値があります。これは、同期に前の行の値があることを示しています。これは私を混乱させる、私はTask.Runとスレッドとは何かがあると思っているが、ローカルスコープの変数が自発的に値を変更している方法を理解していない。

+0

)を終了し、それがなぜそれがこれをするのだろうか。 GetOrdersとGetOrdersAsync()を実際の非同期メソッドとして作成し、GetOrdersを待つことができますか?その後、次の同期を処理しようとする前に待機します。 – Dispersia

答えて

6

syncの参照を更新してから、タスクを操作することができます。タスクは必ずしもすぐに開始するとは限りません。

sync = _common.StartSync(); 

syncをご参照がnullの場合もあり、そして、あなたのタスクは、sync.SyncIdにアクセスするために行くとき、あなたはnull参照の例外を取得:いくつかのケースでは、あなたのタスクは、次のように下にさらに実行された後に起動することがあります。

次にあなたのコードを変更し

if (result) { 
    var syncId = sync.SyncId; 
    Task.Run(() => GetOrders(syncId, customerId)); 
} 

私たちは同上に渡したいので、これは動作します。オブジェクト自体を渡したい場合はどうすればよいですか?あなたクロージャの外に変更されないれる新しい変数を作成する必要があるだろう:もし、あなたのシンク= _common.StartSync()(GetOrders前のあなたの同期オブジェクトを無効に

if (result) { 
    var capturedSync = sync; 
    //Assuming GetOrders now takes a `Sync` 
    Task.Run(() => GetOrders(capturedSync, customerId)); 
} 
+1

最後の例では、それは浅いコピーです。同期を変更すると、capturedSyncも変更されます。彼は深いコピーをする必要があります。私はあなたの最初の例を守ります。 – Dispersia

+2

@Dispersia「同期を変更すると、capturedSyncも変更されます」...あなたはそれについて絶対に確信していますか? – spender

+0

@spenderはい?それは浅いコピーがするものです。自分で試してみて、オブジェクトを作成し、それを割り当てて(これは参照によって行います)、新しいオブジェクトを変更して元の変更を確認してください。 – Dispersia

関連する問題