在IAsyncResult中使用Async方法

编程入门 行业动态 更新时间:2024-10-27 15:22:31
本文介绍了在IAsyncResult中使用Async方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在从实现 TokenProvider 类> Microsoft.ServiceBus 命名空间.我要重写以下方法

I am implementing TokenProvider class from Microsoft.ServiceBus namespace. I am overriding the following method

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 .有解决这个问题的更好方法吗?

But as mentioned in the comment above. GetCustomTokenAsync is an async method and how do I await without disturbing the signature of TokenProvider class? I wanted to make use of async nature of GetCustomTokenAsync and hence I am reluctant to use .Result. Is there any better way of solving this?

推荐答案

您需要围绕TAP方法创建APM包装器.

这并非完全简单,尤其是因为 TokenProvider 的 End * 方法不遵循APM模式.

This is not entirely straightforward, especially because the End* methods of TokenProvider do not follow the APM pattern.

要求和建议:

  • Task 实现了 IAsyncResult ,因此您可以返回任务.
  • 该任务的 state 成员必须从该属性的 IAsyncResult.AsyncState 属性返回,因此您返回的 任务将无法生成通过 async -您必须通过 TaskCompletionSource< T> 自己创建它.
  • 操作完成后,需要调用回调.
  • 如果覆盖 Begin * ,则必须还覆盖匹配的 End * .
  • Task implements IAsyncResult, so you can return a task.
  • The state member has to be returned from the IAsyncResult.AsyncState property on that task, so the task you return cannot be one generated by async - you have to create it yourself via TaskCompletionSource<T>.
  • The callback needs to be invoked when the operation completes.
  • If you override Begin*, you must also override the matching End*.

生成的代码最终变得有点复杂.您可以在我的 AsyncEx.Tasks 库(当前, ApmAsyncFactory 仅位于预发行版本):

The resulting code ends up being a bit complex. You can avoid the boilerplate by using the ApmAsyncFactory.ToBegin in my AsyncEx.Tasks library (currently, ApmAsyncFactory is only in the prerelease build):

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; }

或者,如果您想查看香肠的制作方法以及手工操作,则可以选择一种方法(请记住所有异常情况都可以到达):

Alternatively, if you wanted to see how the sausage is made and do it all by hand, one option would be (keeping in mind where all the exceptions can go):

protected override IAsyncResult OnBeginGetToken(string appliesTo, string action, TimeSpan timeout, AsyncCallback callback, object state) { var tcs = new TaskCompletionSource<SharedAccessSignatureToken>(state, TaskCreationOptions.RunContinuationsAsynchronously); var _ = CompleteAsync(GetCustomTokenAsync(appliesTo), callback, tcs); // _ is ignored; it can never fault. return tcs.Task; } private static async Task CompleteAsync<TResult>(Task<TResult> task, AsyncCallback callback, TaskCompletionSource<TResult> tcs) { try { tcs.TrySetResult(await task.ConfigureAwait(false)); } catch (OperationCanceledException ex) { tcs.TrySetCanceled(ex.CancellationToken); } catch (Exception ex) { tcs.TrySetException(ex); } finally { // Invoke callback unsafely on the thread pool, so exceptions are global if (callback != null) ThreadPool.QueueUserWorkItem(state => callback((IAsyncResult)state), tcs.Task); } } protected override SecurityToken OnEndGetToken(IAsyncResult result, out DateTime cacheUntil) { var task = (Task<SharedAccessSignatureToken>)result; var ret = task.GetAwaiter().GetResult(); cacheUntil = ...; return ret; }

更多推荐

在IAsyncResult中使用Async方法

本文发布于:2023-11-12 02:58:41,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1580312.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:方法   IAsyncResult   Async

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!