简体   繁体   English

同步实现异步方法

[英]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.我已经找到了几个解决方案(await task.Yield()await Task.Run(() => {})) ,但我无法完全理解什么是正确的实现以及为什么。

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如果您不想要 aysnc 方法的开销(与异步“状态机”相关的成本可能不受欢迎),您可以

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

My solution is to return a Task that represents the result of an already executed synchronous method.我的解决方案是返回一个代表已执行同步方法结果的Task 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.如果有人有更好的建议,我会全神贯注。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM