我正在Microsoft.ServiceBus
命名空间中实现TokenProvider类。
我重写了以下方法
protected override IAsyncResult OnBeginGetToken(string appliesTo, string action, TimeSpan timeout, AsyncCallback callback,
object state)
{
var token = GetCustomTokenAsync(appliesTo); //How to await?
return new CompletedAsyncResult<SharedAccessSignatureToken>(token, callback, state);
}
但正如上面的评论所述。 GetCustomTokenAsync是一种异步方法,如何在不打扰TokenProvider类签名的情况下等待?我想利用GetCustomTokenAsync的异步性质,因此我不愿意使用.Result
。有没有更好的方法来解决这个问题?
答案 0 :(得分:2)
您需要create APM wrappers around a TAP method。
这并非完全直截了当,尤其是因为End*
的{{1}}方法不遵循APM模式。
要求和建议:
TokenProvider
实施Task
,因此您可以返回任务。IAsyncResult
属性返回state
成员,因此您返回的任务不能是由IAsyncResult.AsyncState
生成的任务 - 您必须通过async
自己创建。TaskCompletionSource<T>
。callback
,则必须也会覆盖匹配的Begin*
。结果代码最终有点复杂。您可以使用我的AsyncEx.Tasks库中的End*
来避免使用样板文件(目前,ApmAsyncFactory.ToBegin
仅在prerelease build中):
ApmAsyncFactory
或者,如果你想看看如何制作香肠并手工完成,可以选择一种方法(记住所有例外情况都可以):
protected override IAsyncResult OnBeginGetToken(string appliesTo, string action,
TimeSpan timeout, AsyncCallback callback, object state)
{
return ApmAsyncFactory.ToBegin(GetCustomTokenAsync(appliesTo), callback, state);
}
protected override SecurityToken OnEndGetToken(IAsyncResult result,
out DateTime cacheUntil)
{
var ret = ApmAsyncFactory.ToEnd<SharedAccessSignatureToken>(result);
cacheUntil = ...;
return ret;
}
答案 1 :(得分:-3)
我根本不会使用IAsyncResult
,而是应该返回Task<T>
并等待它。您的GetCustomTokenAsync
方法也是如此。