【问题标题】:The 'await' operator can only be used with an async lambda expression [duplicate]'await' 运算符只能与异步 lambda 表达式一起使用 [重复]
【发布时间】:2014-11-04 06:30:56
【问题描述】:

我正在尝试将文件列表复制到目录中。我正在使用异步/等待。 但是我一直收到这个编译错误

“await”运算符只能在异步 lambda 中使用 表达。考虑用“异步”标记这个 lambda 表达式 修饰符。

这就是我的代码的样子

async Task<int> CopyFilesToFolder(List<string> fileList, 
            IProgress<int> progress, CancellationToken ct)
{
    int totalCount = fileList.Count;
    int processCount = await Task.Run<int>(() =>
    {
        int tempCount = 0;
        foreach (var file in fileList)
        {
            string outputFile = Path.Combine(outputPath, file);

            await CopyFileAsync(file, outputFile); //<-- ERROR: Compilation Error 

            ct.ThrowIfCancellationRequested();
            tempCount++;
            if (progress != null)
            {
                progress.Report((tempCount * 100 / totalCount)));
            }

        }

        return tempCount;
    });
    return processCount;
}


private async Task CopyFileAsync(string sourcePath, string destinationPath)
{
    using (Stream source = File.Open(sourcePath, FileMode.Open))
    {
        using (Stream destination = File.Create(destinationPath))
        {
            await source.CopyToAsync(destination);
        }
    }

}

谁能指出我在这里遗漏了什么?

【问题讨论】:

  • 你没有用async关键字标记lambda?基本上,如果你在 Task.Run 中提取了 lambda,它就不是 async 方法,所以你不能等待结果。
  • await Task.Run&lt;int&gt;(() =&gt; ... -- lambda 不是 async
  • 这应该不带 lambda 或 Task.Run,因为它只是 IO 绑定的工作。有关示例解决方案,请参阅 pastebin.com/p83gkkTk(我会将此作为答案发布,但它已经关闭)。
  • @TimS。谢谢,是的,我同意。

标签: c# async-await .net-4.5


【解决方案1】:
int processCount = await Task.Run<int>(() =>

应该是

int processCount = await Task.Run<int>(async () =>

请记住,lambda 只是定义 方法 的简写。因此,您的外部方法是 async,但在这种情况下,您尝试在 lambda 中使用 await(这是一种与外部方法不同的 方法)。所以你的 lambda 也必须标记为 async

【讨论】:

  • await Task.Run&lt;int&gt;(async () =&gt; 对我来说似乎是多余的。有没有更好的写法?
  • @TimS.:不;每个部分都很重要,并且意味着不同的东西。 async () =&gt; 使 lambda asyncTask.Run 在线程池线程上运行该 lambda,await 表示调用方法正在(异步)等待该 lambda 完成。
  • 抱歉,我不清楚:Task.Run 似乎通常用于卸载一些本来会同步的、受 CPU 限制的工作。这似乎没有任何重要的 CPU 工作,只是 IO 绑定工作。那么以不使用Task.Run,而仅使用awaits 异步方法的方式编写它是不是可能更好?
  • 啊,我明白了。是的,使用 Task.Run 进行 I/O 工作是多余的,这里似乎确实如此。
  • 这是我需要的,谢谢! Assert.ThrowsAsync&lt;InvalidOperationException&gt;(async () =&gt; await this.eligibilityService.GetEligibility(eligibilityCriteriaModel)).Result;
猜你喜欢
  • 2014-01-02
  • 2016-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-04
相关资源
最近更新 更多