[英]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.