繁体   English   中英

使用异步/等待进行异步网络编程

[英]Asynchronous network programming with async/await

在过去的几年中,我已经使用异步编程模型和套接字开发了客户端/服务器软件。 MSDN上的此示例尽管复杂化了诸如ManualResetEvents之类的同步机制,但却说明了以下概念:您将BeginXXX()EndXXX()方法对用于连接和流操作。

这样的好处是让线程池根据需要(例如,当接收到数据时)分配线程,而不是每个连接都没有专用线程,这不会扩展。

最近有人提到,也可以使用.NET 4.5中引入的async / await模型来实现此方法,从而使用Tasks并使该情况下不需要APM。 怎么做?

Task Asynchronous Pattern及其使用的关键字async-await允许您以“更干净”的方式使用异步I / O(如您所说)。

无需使用BeginXXXEndXXX方法并在彼此之间传递回调,您只需await返回awaitable的async方法上await即可(A Task是其中的一个示例)。

例如,让我们使用HttpClient进行示例:

public async Task DoGetWebRequestAsync()
{
    var httpClient = new HttpClient();
    await httpClient.GetAsync(url);
}

要做的是,一旦该方法命中了await关键字,它将把控制权交还给调用方法,在幕后创建一个状态机(该状态机将负责执行继续,传播异常等),并IO工作完成后,可通过IOCP(由ThreadPool分配的IO完成端口)恢复。

TAP还提供了一种使用TaskFactory.FromAsync将旧的APM模式转换为TAP的方法:

FileInfo fi = new FileInfo(path);
byte[] data = null;
data = new byte[fi.Length];

FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read,
                               FileShare.Read, data.Length, true);

//Task<int> returns the number of bytes read
Task<int> task = Task<int>.Factory.FromAsync(
        fs.BeginRead, fs.EndRead, data, 0, data.Length, null);

编辑:

如何使用async很简单。 例如,使用FileStream

public async Task<byte[]> ReadBufferAsync(string path)
{
    FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read,
                                FileShare.Read, data.Length, true);

    // Read some bytes, not all, just for the example.
    byte[] buffer = new byte[2048];
    await fs.ReadAsync(buffer, 0, buffer.Length);

    return buffer;
}

您将方法标记为async以便可以在其中使用await关键字,然后仅在读取的方法上await

实际上,由Socket类支持的旧APM使用了特殊的线程池IOCP(“ I / O完成端口”)线程池,而不是在“接收数据时”分配线程,而是将线程实际分配为I / O操作启动 ,但以允许单个线程(或少量线程,例如与系统上的内核一样多的线程)的方式处理大量套接字对象和操作。

至于如何使用新的async / await样式的API,不幸的是Socket类没有得到任何直接的async爱。 但是,所有包装程序都做到了。 最简单的替换方法是使用NetworkStream类,并使用ReadAsync()WriteAsync() ,它们是可以等待的方法。

如果您仍然想直接使用Socket API(本质上),则必须使用等待的实现将其包装起来。 恕我直言,这里是一个很好的资源,它解释了一种可行的方法: 等待套接字操作

暂无
暂无

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

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