在 IAsyncResult 中使用异步方法

2023-12-13

我正在实施令牌提供者班级来自Microsoft.ServiceBus命名空间。 我正在重写以下方法

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


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

这并不完全简单,特别是因为End*的方法TokenProvider do not遵循 APM 模式。

要求和建议:

  • Task实施IAsyncResult,这样您就可以返回任务。
  • The state会员必须从IAsyncResult.AsyncState该任务的属性,因此您返回的任务cannot是由以下生成的之一async- 你必须通过以下方式自己创建它TaskCompletionSource<T>.
  • The callback操作完成后需要调用。
  • 如果你覆盖Begin*, you must也覆盖匹配End*.

生成的代码最终有点复杂。您可以通过使用来避免样板ApmAsyncFactory.ToBegin in my AsyncEx.任务图书馆(目前,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;
}

或者,如果您想看看香肠是如何制作的并全部手工制作,一个选择是(记住所有例外情况都可以去哪里):

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;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 IAsyncResult 中使用异步方法 的相关文章

随机推荐

  • CSS 边框小于 1px [重复]

    这个问题在这里已经有答案了 可能的重复 HTML 子像素边框 默认border 1px太大了 然而 border 0 5px solid 不管用 有没有一种 CSS 解决方案可以使边框大小减半 像素是渲染物体的最小单位值 但是您可以通过修改
  • sencha touch 消息框不可点击

    在 sencha touch 中 我们在消息框方面遇到了一些问题 看起来是android 4 3的东西 在大多数设备上它都可以完美工作 但在 Android 4 3 的设备上 当用户按下按钮时 消息框不会消失 Ext define Test
  • addChildViewController 实际上做了什么?

    我刚刚第一次涉足 iOS 开发 我要做的第一件事就是实现一个自定义容器视图控制器 我们称之为SideBarViewController 交换它显示的几个可能的子视图控制器中的哪一个 几乎与标准完全相同标签栏控制器 这几乎是一个标签栏控制器但
  • HTML:防止 POST 表单的 url 编码

    我有一个 HTML 表单 必须将其发布到 URL 我希望表单能够发布一个名为 DATA 的变量 如下所示 DATA somevar someval somevar2 someotherval 我在做这件事时遇到了麻烦 看来默认情况下 会对数
  • iOS 的免费语音识别引擎?

    我正在寻找一些免费的语音识别引擎来在我的 iPhone 应用程序中使用 你能推荐吗 Nuance 刚刚为开发人员打开了大门龙移动SDK 他们是行业领导者 看一下NDEV 移动
  • Swift 3.0 和 Xcode 8 迁移后未调用 UITableViewDelegate 方法

    将我的代码库从 Swift 2 2 迁移到 Swift 3 0 后 我注意到我的UITableView页脚没有显示 事实证明我的都没有UITableViewDelegate方法被调用 例如 func tableView tableView
  • 如何从 PHP 解析以文本/xml 形式发送到服务器的 XML?

    我有一个用 jQuery 编写的客户端脚本 它将文本 xml 数据发送到服务器 但我不知道如何解析请求 因为数据不是查询字符串变量 jQuery 看起来像这样 jQuery ajax url test php type POST proce
  • Jetty 9 及更高版本中的 SelectChannelConnector 替代类

    jetty 9及以上版本的SelectChannelConnector的替代类是什么 另外 SelectChannelConnector 类有什么用 连接器类在 jetty servlet 架构中有何用途 我们可以使用 ServerConn
  • Python正则表达式提取日期

    我的字符串看起来像这样 server date YYYYMMDD int server date MON DAY YYYY int 还有更多 不同的日期格式 此外 可以有任意数量的 块 并且它们可以以任意顺序出现 我试图获取 Python
  • 如何通过 Docusign API 将动态图像添加到 Docusign 文档

    我不知道 Docusign API 是否可以实现这一点 但我很好奇是否可以将动态图像添加到模板文档中 此动态图像的目的是根据发送者的身份为文档设置徽标 我知道 Docusign 有品牌 但我们希望此图像位于模板文档的特定位置 如果有人知道这
  • 1 到 100 之间的正则表达式编号

    我搜索了很多 找不到这个 RegExp 的解决方案 我不得不说我在 Reg Expressions 方面不是很有经验 Regex 1 9 0 9 1 100 我想测试一个数字1 到 100 之间 不包括 0 Try 1 9 0 9 100
  • 参数类型可能存在的时间不够长

    我有一个简单的程序 我试图实现多态帐户类型 enum AccountType INVALID TYPE1 TYPE2 trait Account fn get name self gt String fn get type self gt
  • JToken.WriteToAsync 不写入 JsonWriter

    我正在尝试创建一个以某种方式更改请求的中间件 我能够阅读它并更改内容 但我无法弄清楚如何正确设置流编写器来创建新的正文 当我打电话时normalized WriteToAsync jsonWriter the MemoryStream仍然是
  • VS2017 和 VS2015 应用程序与 dll 之间的官方二进制不兼容性是否准确?

    TL DR MS 文档指出 VS2015 和 VS2017 库之间的二进制兼容性是one way 虽然我认为这必然是双向的 问题在哪里 首先 背景 任何 MSVC 构建的库都是正式二进制兼容VS2015 和 VS2017 之间 具体来说 您
  • sqldf、csv 和包含逗号的字段

    我花了一段时间才弄清楚这一点 我也是回答我自己的问题 您有一些 csv 您想要加载它fast 你想使用sqldf包裹 您常用的代码会被一些烦人的字段所困扰 例子 1001 Amy 9 43 00 99 2 1002 Ben Jr 9 43
  • HTTPS URL 是否加密?

    使用 TLS SSL HTTPS 加密时是否所有 URL 均已加密 我想知道 因为我希望在使用 TLS SSL HTTPS 时隐藏所有 URL 数据 如果 TLS SSL 为您提供全面的 URL 加密 那么我就不必担心隐藏 URL 中的机密
  • 为什么我的 WCF 服务不使用我的实体模型?

    我在同时使用 WCF 服务和实体模型时遇到问题 我已经从现有数据库创建了一个实体模型 这可以如下所示 在来自 实体对象代码生成器 的任何控制台应用程序中使用我的类时没有任何问题 然后 我创建了 WCF 服务 其接口如下 ServiceCon
  • python 正则表达式包含缺少的逗号

    我需要确保字符串具有逗号分隔的值 我读取的字符串可能有空格分隔的值 我的输入字符串中可能缺少一些逗号 也就是说 如果存在任何空格分隔的值而没有逗号 我必须包含一个逗号 我不应该对单引号或双引号内的字符串进行任何更改 这些带引号的值可以包含除
  • 如何以编程方式快速调用 UIView 上的手势点击

    我有一个 UIView 并且我向它添加了点击手势 let tap UITapGestureRecognizer target self action Selector handleTap tap delegate self myView a
  • 在 IAsyncResult 中使用异步方法

    我正在实施令牌提供者班级来自Microsoft ServiceBus命名空间 我正在重写以下方法 protected override IAsyncResult OnBeginGetToken string appliesTo string