2015-04-22 41 views
1

我想使用Parallel.For和異步等待將一些任意GPS數據(1.5億條記錄)加載到Azure表存儲中。但我在第一個await聲明中遇到以下錯誤:在異步lambda表達式中使用await運算符的錯誤

「await」運算符只能在異步lambda表達式中使用。考慮用'async'修飾符標記這個lambda表達式。

這裏是我的代碼:

private static async Task GenerateGpsPointsForTruckAsync(int counter, CloudTableClient tableClient) 
    { 
     // Create a dummy VIN 
     string vin = counter.ToString("D17"); 

     Random random = new Random(); 

     DateTime start = new DateTime(2010, 1, 1); 
     int range = (DateTime.Today - start).Milliseconds; 

     // Create the batch operation. 
     TableBatchOperation batchOperation = new TableBatchOperation(); 

     // Prepare 10 batches of 100 GPS points 
     Parallel.For(0, 10, i => 
     { 
      for (int j = 0; j < 99; j++) 
      { 
       Location location = new Location(vin, start.AddDays(random.Next(range)).ToString()); 

       location.Coordinates = new GeoCoordinate(random.Next(30, 45), random.Next(75, 100)); 

       batchOperation.Insert(location); 
      } 

      await Task.Run(async() => 
      { 
       await LoadGpsPointsForTruckAsync(tableClient, batchOperation); 
      }); 
     }); 
    } 

我看着堆棧溢出一些解決方案,但他們似乎並沒有爲我工作。

+0

似乎沒有什麼是工作? – i3arnon

+2

我想你錯過了'Parallel.For(0,10,i => ...'line上創建的lambda上的'async'修飾符。你能不能嘗試在那裏添加一個? –

+0

你爲什麼要'等待Task.Run(...'而不是簡單的'等待LoadGpsPointsForTruckAsync(...);' – Alex

回答

3

您不能在Parallel.For內部使用異步等待,因爲它比異步更舊,並且不等待它(您可能不想這樣做)。

如果你想創建一個線程池運行多個任務,你可以做到這一點與多次調用Task.RunTask.WhenAll這樣你就可以await它們全部完成:

await Task.WhenAll(Enumerable.Range(0,10).Select(i => Task.Run(() => Foo(i)))); 

這是適當的時候操作是同步的。如果它是異步的,除非你有理由這麼做,否則不應該將它卸載到線程池中。您可以直接調用該方法,並等待結果:

await Task.WhenAll(Enumerable.Range(0,10).Select(i => FooAsync(i))); 
0

Parallel.For期待您來標記它作爲async拉姆達爲好,因爲你outter await Task.Run的:

Parallel.For(0, 10, async() => /* code */) 

但是,async-await不使用Parallel可以很好地發揮作用,因爲它可以通過Action代表將其lambda轉換爲async void

似乎LoadGpsPointsForTruckAsync本身是異步,你可以保存自己的並行循環:

var coordinateTasks = Enumerable.Range(0, 100).Select(_ => 
      { 
       Location location = new Location(vin, 
            start.AddDays(random.Next(range)) 
            .ToString()) 
       { 
        Coordinates = new GeoCoordinate(random.Next(30, 45), 
                random.Next(75, 100)); 
       } 

       batchOperation.Insert(location); 

       return LoadGpsPointsForTruckAsync(tableClient, batchOperation); 
      } 

await Task.WhenAll(coordinateTasks); 
相關問題