使用 async await 时使用 Interlocked.Add 到 Task.Add
Using Interlocked.Add to Task.Add when using async await
我正在尝试将以下代码转换为 async/await:
long deletedBlobCount = 0;
Parallel.ForEach(BlobURLList, item => Interlocked.Add(ref deletedBlobCount, DeleteBlob(item)));
DeleteBlob(item)
函数 returns 如果删除了 blob,则为 1,否则为 0。这是我的新代码的样子(我在 .Net 4 上):
long deletedBlobCount = 0;
var deleteBlobTask = new List<Task>();
foreach (var item in BlobURLList)
{
deleteBlobTask.Add(t => { Interlocked.Add(ref deletedBlobCount, await DeleteBlobAsync(item))});
}
编译器不喜欢这里的 await DeleteBlobAsync(item)。这是错误:
'await' 运算符只能在异步 lambda 表达式中使用。考虑使用 'async' 修饰符
标记此 lambda 表达式
我错过了什么?此外,我无法将 deletedBlobCount 设置为 class 级别变量(日志记录要求)。
在异步方法中试试这个:
long deletedBlobCount = 0;
var deleteBlobTask = new List<Task>();
foreach (var item in BlobURLList)
{
deleteBlobTask.Add(((Func<Task>)(async () => {
long sum = await DeleteBlobAsync(item);
Interlocked.Add(ref deletedBlobCount, sum);
}))());
}
您的代码有几个问题。该特定的编译器错误是在抱怨您在未标记 async
的 lambda 函数中使用 await
。它期待这样的事情:
deleteBlobTask.Add(async () => { Interlocked.Add(ref deletedBlobCount, await DeleteBlobAsync(item)); });
我还删除了 t
参数,因为您没有使用它。
请注意,您在结束 }
之前还遗漏了一个分号。在 one-liner lambda 中,如果省略大括号,则只能省略分号,如下所示:
deleteBlobTask.Add(async () => Interlocked.Add(ref deletedBlobCount, await DeleteBlobAsync(item)) );
但是,仍然无法编译,因为 lambda 表达式是一个 Func<Task>
:一个 returns 是 Task
的函数。您真正想要的是 Task
,或者换句话说,您想要 运行 宁那个函数的结果,而不是函数本身。如您所见,该功能不是 运行.
同时声明一个内联函数(lambda)和运行它,语法有点复杂:
deleteBlobTask.Add(new Func<Task>(async () => Interlocked.Add(ref deletedBlobCount, await DeleteBlobAsync(item)))() );
请注意,您声明了 Func<Task>
,然后将 ()
放在末尾,就像调用任何方法一样。
所以....这很复杂。你确定这一切比仅仅好得多吗:
foreach (var item in BlobURLList)
{
deletedBlobCount += await DeleteBlobAsync(item);
}
我正在尝试将以下代码转换为 async/await:
long deletedBlobCount = 0;
Parallel.ForEach(BlobURLList, item => Interlocked.Add(ref deletedBlobCount, DeleteBlob(item)));
DeleteBlob(item)
函数 returns 如果删除了 blob,则为 1,否则为 0。这是我的新代码的样子(我在 .Net 4 上):
long deletedBlobCount = 0;
var deleteBlobTask = new List<Task>();
foreach (var item in BlobURLList)
{
deleteBlobTask.Add(t => { Interlocked.Add(ref deletedBlobCount, await DeleteBlobAsync(item))});
}
编译器不喜欢这里的 await DeleteBlobAsync(item)。这是错误: 'await' 运算符只能在异步 lambda 表达式中使用。考虑使用 'async' 修饰符
标记此 lambda 表达式我错过了什么?此外,我无法将 deletedBlobCount 设置为 class 级别变量(日志记录要求)。
在异步方法中试试这个:
long deletedBlobCount = 0;
var deleteBlobTask = new List<Task>();
foreach (var item in BlobURLList)
{
deleteBlobTask.Add(((Func<Task>)(async () => {
long sum = await DeleteBlobAsync(item);
Interlocked.Add(ref deletedBlobCount, sum);
}))());
}
您的代码有几个问题。该特定的编译器错误是在抱怨您在未标记 async
的 lambda 函数中使用 await
。它期待这样的事情:
deleteBlobTask.Add(async () => { Interlocked.Add(ref deletedBlobCount, await DeleteBlobAsync(item)); });
我还删除了 t
参数,因为您没有使用它。
请注意,您在结束 }
之前还遗漏了一个分号。在 one-liner lambda 中,如果省略大括号,则只能省略分号,如下所示:
deleteBlobTask.Add(async () => Interlocked.Add(ref deletedBlobCount, await DeleteBlobAsync(item)) );
但是,仍然无法编译,因为 lambda 表达式是一个 Func<Task>
:一个 returns 是 Task
的函数。您真正想要的是 Task
,或者换句话说,您想要 运行 宁那个函数的结果,而不是函数本身。如您所见,该功能不是 运行.
同时声明一个内联函数(lambda)和运行它,语法有点复杂:
deleteBlobTask.Add(new Func<Task>(async () => Interlocked.Add(ref deletedBlobCount, await DeleteBlobAsync(item)))() );
请注意,您声明了 Func<Task>
,然后将 ()
放在末尾,就像调用任何方法一样。
所以....这很复杂。你确定这一切比仅仅好得多吗:
foreach (var item in BlobURLList)
{
deletedBlobCount += await DeleteBlobAsync(item);
}