使用 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);
}