Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Execution of C# Lambda expressions based on async annotations

I am trying to find an elegant implementation of the Execute(..) method below that takes in a lambda expression. Is what I'm trying to do even possible? It seems like I should be able to because the compiler will allow me to pass such a lambda expression (in the form of an Action).

    static void Main(string[] args)
    {
        // This should execute SomeOperation() synchronously
        Execute(() => SomeOperation());

        // This should begin execution of SomeOperationAsync(), but not wait (fire and forget)
        Execute(() => SomeOperationAsync());

        // This should await the execution of SomeOperationAsync() (execute synchronously)
        Execute(async () => await SomeOperationAsync());
    }

How would you implement the Execute method above given these specifications?

like image 855
Craig Smitham Avatar asked Oct 02 '22 16:10

Craig Smitham


1 Answers

You could check whether the method underlying the delegate you've been passed is annotated with the AsyncStateMachineAttribute - but to be honest, I wouldn't. It's just asking for trouble, using an implementation detail like that.

Instead, I'd have a separate overload of ExecuteAsyncDelegate which took a Func<Task> instead of just Action. You need to be careful about what you do within that, of course - you quite possibly don't want to just block the executing thread. You may want to consider making this an async method as well. (It's not clear what your Execute method is meant to do other than just call the delegate - presumably it's adding value somewhere.)

For example, suppose you were actually doing this for timing purposes. You might have:

static async Task<TimeSpan> BenchmarkAsync(Func<Task> func)
{
    Stopwatch sw = Stopwatch.StartNew();
    await func();
    sw.Stop();
    return sw.Elapsed;
}
like image 119
Jon Skeet Avatar answered Oct 16 '22 07:10

Jon Skeet