IO完成端口(IOCP)

时间:2014-01-19 13:14:20

标签: c# sql wcf asynchronous io

当我调用BeginExecuteReader(SQL)时,它是否使用IO完成端口?是什么使它成为异步?我应该从Begin[Operation]()还是从IAsyncResult构造函数的包装器中调用它?

2 个答案:

答案 0 :(得分:4)

  

是否使用IO完成端口

可能,但这是本机SQL客户端实现的深层实现细节。

记住SQL Server ADO.NET调用(本地)本机SQL Server客户端,它将执行与服务器的通信。

  

是什么让它成为异步?

它的实施。有多种方法可以做到这一点,从伪造它的方法(使用专用工作线程执行阻塞操作)到IO完成端口和其他“真正的”异步API。

  

我应该从哪里打电话?

设计的正确位置。

  

for IAsyncResult构造函数?

如何使用异步API(回调传递给BeginExecuteReader,轮询返回的IAsyncResultIsComplete,等待IAsyncResult,转换为Task } TaskFactory.FromAsync,使用带有Observable.FromAsyncPattern的Reactive Extensions或其他内容)再次成为 代码设计的一部分。

提供任何形式的指导的可能性太多了。

答案 1 :(得分:1)

该方法是否使用IO完成端口取决于实现。

如果在完成工作之前返回,则调用是异步的。显然,这也取决于实施。

使用它的标准方法是

{
    ...
    var fs = new FileStream(...); // using FileStream as an example
    var data = new byte[100];
    var ar = fs.BeginRead(data, 0, 100, MyCallback, new object[] { fs, data });
    ...
    // you can check the IAsyncResult ar for completion,
    // or do some work that doesn't depend on the data
}

private void MyCallback(IAsyncResult ar)
{
    // AsyncState gets the last parameter from the call to BeginRead
    var fs = (FileStream)(((object[])ar.AsyncState)[0]);
    var data = (FileStream)(((object[])ar.AsyncState)[1]);

    int numberOfBytesRead = fs.EndRead(ar);
    // do something with data
}

当然,您也可以使用lambda表达式作为回调。对于lambdas,状态不必手动捕获,因此您可以像

一样使用它
var ar = fs.BeginRead(data, 0, 100, result => 
{
    int numberOfBytesRead = fs.EndRead(result);
    // do something with data
}, null);