有没有办法同步运行异步lambda?

时间:2017-04-12 12:41:03

标签: c# multithreading lambda async-await

有没有办法同步运行异步lambda?不允许修改lambda表达式,它必须按原样保留。

复制/粘贴示例(它是一个抽象):

var loopCnt = 1000000;

Action<List<int>> aslambda = async (l) =>
{
    Thread.Sleep(100);
    await Task.Run(() => { });
    for (int i = 0; i < loopCnt; i++) { l.Add(i); }
};

var lst = new List<int>();
aslambda(lst); //This runs asynchronously 
if (lst.Count < loopCnt-100) { ; }

解决方案:

真的让我接受一个答案是一个两难选择。我已经尝试了使用NuGet包的 Stephen Cleary 的解决方案 - 工作精彩且广泛适用,但 dvorn 对问题的回答(因为它已经制定) ;))更容易。

dvorn 是否改变了lambda的签名?不,是;)

来自MSDN:

  

请注意,lambda表达式本身没有类型,因为   普通类型系统没有&#34; lambda的内在概念   。表达&#34;但是,非正式地说话有时很方便   &#34;类型&#34;一个lambda表达式。在这些情况下,类型是指   到lambda表达式的委托类型或表达式类型   转换。

所以两者都接受 +1 并接受 Stephen Cleary的答案

2 个答案:

答案 0 :(得分:5)

  

有没有办法同步运行async [void] lambda?

是的,但与所有sync-over-async hacks一样,它很危险,并且对所有lambdas都不起作用。

您必须拥有custom SynchronizationContext to detect the completion of an async void method(或lambda)。这非常重要,但您可以使用我的AsyncContext(在NuGet包Nito.AsyncEx.Context中提供):

AsyncContext.Run(() => aslambda(lst));

答案 1 :(得分:2)

更好的解决方案:您无法更改lambda,但您可以更改分配给它的局部变量的类型。请注意,异步lambda的本机类型不是Action而是Func&lt; Task&gt;。

...
Func<List<int>, Task> aslambda = async (l) =>
...
...
aslambda(lst).Wait();
...