【问题标题】:Moving from Asynchronous Programming Model (APM) to Task-based Asynchronous Pattern (TAP)从异步编程模型 (APM) 到基于任务的异步模式 (TAP)
【发布时间】:2014-06-19 17:01:35
【问题描述】:

.NET 中有很多类使用旧的 Asynchronous Programming Model (APM)“不再推荐用于新开发”。 APM 使用 Begin/End 方法对,End 方法将IAsyncResult 对象作为参数。一个这样的类是TcpClient,您可以使用它进行异步连接,如下所示:

private void SomeMethod()
{
    this.tcpClient = new TcpClient();
    IAsyncResult result = this.tcpClient.BeginConnect(ip, port, EndConnect, null);
}

private void EndConnect(IAsyncResult asyncResult)
{
    this.tcpClient.EndConnect(asyncResult);

    // ... do stuff ...
}

Task-based Asynchronous Pattern (TAP) 是一种更现代的异步编程形式,可通过使用 asyncawait 关键字来实现。

如果你有一个像 TcpClient 这样的类,它使用 APM 模型并且不公开任何任务,那么如何将其异步方法调整到 TAP 以便它们可以与async/await 一起使用?

【问题讨论】:

    标签: c# asynchronous task async-await


    【解决方案1】:

    我是in the documentation you linked to

    作为一般规则,您应该首先查看或询问直接支持 TAP 的更新 API。几乎所有 BCL 类都已更新为支持 TAP,并且少数(例如 HttpWebRequest)已被 TAP 替代品(例如 HttpClient)取代。在这种情况下,没有 TAP TcpClient 等效项,因此最好将它们包装起来。

    如果您确实在 APM 包装器上编写 TAP,我建议使用简单的扩展方法:

    public static Task ConnectTaskAsync(this TcpClient client, IPAddress address, int port)
    {
      return Task.Factory.FromAsync(client.BeginConnect, client.EndConnect, address, port, null);
    }
    

    这为您提供了一种使用它们的自然方式,并将您的“互操作”代码与任何包含实际逻辑的代码分开:

    async Task SomeMethodAsync()
    {
      this.tcpClient = new TcpClient();
      await this.tcpClient.ConnectTaskAsync(ip, port);
      // ... do stuff ...
    }
    

    【讨论】:

      【解决方案2】:

      您可以为此使用Task.Factory.FromAsync。示例(对于BeginReceive/EndReceive):

      public static class SocketsExt
      {
          static public Task ReceiveDataAsync(
              this TcpClient tcpClient,
              byte[] buffer)
          {
              return Task.Factory.FromAsync(
                  (asyncCallback, state) =>
                      tcpClient.Client.BeginReceive(buffer, 0, buffer.Length, 
                          SocketFlags.None, asyncCallback, state),
                  (asyncResult) =>
                      tcpClient.Client.EndReceive(asyncResult), 
                  null);
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-25
        • 1970-01-01
        相关资源
        最近更新 更多