异步lambda在等待方法返回之前不返回

时间:2015-04-07 12:04:34

标签: .net asynchronous async-await

我试图开始使用.net 4.5中的异步方法,我认为我已经弄明白了,但是现在当我试图在func中执行它但我不能让以下工作:

Action task = async () =>
    {

            await _db.SaveChangesAsync();
            Debug.WriteLine("Save completed");

    };

task();

Debug.WriteLine("Returned");           

输出将是: 保存完成 返回

我预计它的顺序相反。

有什么想法吗?

谢谢!

编辑1:

我已经创建了一个示例代码来显示我想要的内容,而奇怪的是它完美运行:

    static void Main(string[] args)
    {
        using (BCFdbEntities db = new BCFdbEntities())
        {
            IssueComment ic = db.IssueComments.First();

            ic.Comment = DateTime.Now.ToString() ;

            Action a = async () =>
                {
                    await db.SaveChangesAsync();

                    Console.WriteLine("Save completed");

                };

            a();
            Console.WriteLine("Returned");

            Console.ReadLine();

        }



    }
}

但是,我无法在我的实时代码中使用完全相同的代码。 代码是商业工具的插件的一部分,他们可能会以某种方式阻止它吗?

2 个答案:

答案 0 :(得分:0)

  

我预计它的顺序相反。

抱歉,你不能指望任何事情。这是竞争条件。

如果您想等待代码完成,则无法使用Action。你真的不应该Action使用async lambdas,因为他们创建了一个async void方法。你应该避免async void(我的MSDN article中的更多细节)。

相反,您需要使用async等效的ActionFunc<Task>(我更多地描述on my blog)。使用Func<Task>,您的调用代码现在可以await执行lambda:

Func<Task> task = async () =>
{
  await _db.SaveChangesAsync();
  Debug.WriteLine("Save completed");
};

await task();
Debug.WriteLine("Returned");

答案 1 :(得分:0)

我想我解决了。 保存速度非常快,无法等待该方法。 我添加了Task.Delay(5000)来减慢速度以查看是否是这种情况然后它按预期工作。在此之后,我测量了执行的时间,它只有12毫秒,不太确定如何测量异步方法,所以我包含了比可能需要的更多的代码。

            Stopwatch sw = new Stopwatch();
            sw.Start();

            Func<Task> task = async () =>
            {
               // await Task.Delay(5000);
                await _db.SaveChangesAsync();
                Debug.WriteLine("Save completed");
            };

            task();
            Debug.WriteLine("Returned");

            sw.Stop();

无论如何,我没想到编译器会想知道是否要等待一个方法,但显然它确实如此。

感谢Stephen Cleary关于Func而不是Action的建议。我将确保将来使用它!