Clark Kent
Clark Kent

Reputation: 315

Implement async method synchronously

I have an interface which forces me to implement an (async) Task:

namespace Microsoft.Owin.Security.Infrastructure
{
    public interface IAuthenticationTokenProvider
    {
        ..
        Task CreateAsync(AuthenticationTokenCreateContext context);
        ..
    }
}

I want to implement this method, but I'm not awaiting anything. Although I have to await something or return some task, otherwise my code does not compile.:

public class MyImplementation: IAuthenticationTokenProvider
{
    public async Task CreateAsync(AuthenticationTokenCreateContext context) 
    {
        /// do something synchronously.

        await something here? ??
    }
}

My question is: How would I implement this method without doing something asynchronously? I've have found a couple of solutions (await task.Yield(), or await Task.Run(() => {})), yet I can't fully understand what would be the correct implementation and why.

Upvotes: 3

Views: 1333

Answers (2)

Darren Clark
Darren Clark

Reputation: 793

My solution is to return a Task that represents the result of an already executed synchronous method. That way you maintain the semantics an async method with regard to when the exception gets surfaced, without the overhead of the async state machine. Funny enough, I actually did this for the same reason on this same interface

I have an extension method:

    public static Task AsCompletedTask<T>(this Action<T> func, T arg)
    {
        var tcs = new TaskCompletionSource<VoidResult>();
        try
        {
            func(arg);
            tcs.SetResult(voidResult);
        }
        catch (Exception e)
        {
            tcs.SetException(e);
        };

        return tcs.Task;
    }

Which then I invoke via:

    public Task CreateAsync(AuthenticationTokenCreateContext context)
    {
        return ((Action<AuthenticationTokenCreateContext>)Create).AsCompletedTask(context);
    }

BTW, I hate that name. If anyone has a better suggestion, I'm all ears.

Upvotes: 0

spender
spender

Reputation: 120380

Just implement the method without awaiting:

public async Task<Foo> GetFooAsync()
{
    return new Foo();
}

It doesn't matter that you're not awaiting anything. It's not a requirement of an async method to await anything (although the compiler will warn you that you're not awaiting anything).

If you don't want the overhead of an aysnc method (there's a cost associated with the async "state machine" that might be undesirable), you could

public Task<Foo> GetFooAsync()
{
    return Task.FromResult(new Foo());
}

Upvotes: 2

Related Questions