Reputation: 7325
Is there a way to run async lambda synchronously? It is not allowed to modify lambda expression, it must be leaved as is.
Copy/paste example(it's an abstraction):
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) { ; }
It is really a dilemma for me to accept one answer. I have tried out the solution from Stephen Cleary with NuGet package - works brilliant and is broad applicable, but an answer from dvorn to the question(as it's formulated ;)) is much easier.
Has dvorn changed the signature of lambda? No and Yes ;)
Note that lambda expressions in themselves do not have a type because the common type system has no intrinsic concept of "lambda expression." However, it is sometimes convenient to speak informally of the "type" of a lambda expression. In these cases the type refers to the delegate type or Expression type to which the lambda expression is converted.
So both receive +1 and accepted answer by Stephen Cleary
Upvotes: 7
Views: 2682
Reputation: 3147
Better solution: You cannot change the lambda, but you may change the type of local variable it is assigned to. Note that native type of async lambda is not Action but Func<Task>.
...
Func<List<int>, Task> aslambda = async (l) =>
...
...
aslambda(lst).Wait();
...
Upvotes: 2
Reputation: 457472
Is there a way to run async [void] lambda synchronously?
Yes, but like all sync-over-async hacks, it's dangerous and won't work for all lambdas.
You must have a custom SynchronizationContext
to detect the completion of an async void
method (or lambda). This is non-trivial, but you can use my AsyncContext
(available in the NuGet package Nito.AsyncEx.Context
):
AsyncContext.Run(() => aslambda(lst));
Upvotes: 6