繁体   English   中英

从异步编程模型(APM)迁移到基于任务的异步模式(TAP)

[英]Moving from Asynchronous Programming Model (APM) to Task-based Asynchronous Pattern (TAP)

.NET中有许多类使用旧的异步编程模型(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 ...
}

基于任务的异步模式(TAP)是一种更现代的异步编程形式,通过使用asyncawait关键字来促进。

因此,如果您有一个类似TcpClient的类,它使用APM模型并且不公开任何任务,那么如何将其异步方法适配到TAP以便它们可以与async / await一起使用?

位于您链接的文档中

作为一般规则,您应首先查看或询问有关直接支持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 ...
}

您可以使用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);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM