有没有办法同步运行异步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的签名?不,是;)
请注意,lambda表达式本身没有类型,因为 普通类型系统没有&#34; lambda的内在概念 。表达&#34;但是,非正式地说话有时很方便 &#34;类型&#34;一个lambda表达式。在这些情况下,类型是指 到lambda表达式的委托类型或表达式类型 转换。
所以两者都接受 +1 并接受 Stephen Cleary的答案
答案 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();
...