我正在尝试使用Parallel.For和async await将一些任意GPS数据(1.5亿条记录)加载到Azure Table存储中。但是我在第一个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);
});
});
}
我在Stack Overflow上查看了一些解决方案,但它们似乎并不适合我。
答案 0 :(得分:3)
你不能在Parallel.For
内使用async-await,因为它比async更早,并且没有等待它(你可能不想要)。< / p>
如果要创建在线程池上运行的多个任务,可以通过Task.Run
与Task.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)));
答案 1 :(得分:0)
Parallel.For
期待您将其lambda标记为async
,因为您的{$ 1}}:
await Task.Run
但是Parallel.For(0, 10, async () => /* code */)
与async-await
无法很好地配合,因为它通过Parallel
代表将其lambda转换为async void
。
似乎Action
本身是异步的,你可以保存自己的并行循环:
LoadGpsPointsForTruckAsync