C# 任务中的异步lambda与常规lambda。运行

C# 任务中的异步lambda与常规lambda。运行,c#,task-parallel-library,C#,Task Parallel Library,假设我有一个方法,它通过一些异步调用运行一个连续while循环 async Task MethodA(){ while(true){ perform async/await operations } } 以下两者之间的区别是什么: Task.Run( () => MethodA(); } Task.Run( async () => await MethodA(); } 如果有区别,什么时候一个比另一个更有用 根据斯蒂芬·克利里(Stephen Cleary)在《答案》(a

假设我有一个方法,它通过一些异步调用运行一个连续while循环

async Task MethodA(){
    while(true){ perform async/await operations }
}
以下两者之间的区别是什么:

Task.Run( () => MethodA(); }
Task.Run( async () => await MethodA(); }

如果有区别,什么时候一个比另一个更有用

根据斯蒂芬·克利里(Stephen Cleary)在《答案》(answer)中的答案和他链接的博客文章,唯一的区别在于第二个答案创建了一个状态机。在这里,您可以使用第一种情况,而不存在任何缺点

以下是您可以遵循的一些准则:

  • 默认情况下不要删除。使用async和Wait以获得自然、易读的代码
  • 当该方法仅仅是通过或过载时,请考虑省略;<李>
  • 如果希望方法显示在堆栈跟踪中,请不要删除
完整地说,根据这里的另一个答案: 将在线程池中对函数的结果进行排队,当排队的任务完成(包括所有等待)时,生成的函数将完成

Task.Run(MethodA)
将该方法转换为委托并将其传递

Task.Run(()=>MethodA())
将创建一个隐藏方法,该方法将返回
方法a
的结果(正是这个隐藏方法将转换为委托并传递)

Task.Run(async()=>await MethodA())
将创建一个包含wait的隐藏方法,但如前所述,它将转换为一个状态机,最终将
MethodA()
的结果包装到一个新的
任务中

Task.Run(()=>{MethodA();})
是完全不同的,因为有花括号,这将调用重载,在本例中,
MethodA()
将在此任务上运行,直到它到达第一个未完成的等待,然后完成。此
任务不会监视此内部任务完成后(内部等待后)发生的情况。Run
将继续在线程池上运行,如果它引发异常,可能会导致应用程序崩溃。原因是
MethodA
返回的任务由于缺少关键字
return
而被忽略


Task.Run(()=>{returnmethoda();})
是此异常的修复程序,将与所有其他示例一样工作。

有相当大的区别
MethodA()
返回一个
任务
。如果您不等待该
任务的结果
,则处理将继续正常进行

MethodA()
在任务到达内部等待时返回任务。lambda现在已经完成(它调用了
MethodA()
并获得了一个返回值),因此
Task.Run()
将把它自己的任务标记为完成,线程将被释放

Task.Run( async () => await MethodA(); }

lambda是异步的,您正在等待
MethodA()
的真实结果。由
Task.Run()
返回的
任务在MethodA()完成之前不会完成。

这是否回答了您的问题?
Task.Run( async () => await MethodA(); }