异步方法如何在C#中工作?

Mar*_*tin 7 c# asynchronous .net-3.5

我在我的一些项目中使用异步方法,我喜欢它,因为它允许我的应用程序更具可伸缩性.但是,我想知道异步方法在后台如何真正起作用?.NET(或Windows?)如何知道呼叫已完成?根据我所做的异步调用的数量,我可以看到创建了新线程(但并不总是......).为什么?

另外,我想监控请求完成的时间.为了测试这个概念,我编写了以下代码,它在启动秒表后立即异步调用Web服务.

for (int i = 0; i < 10000; i++)
{
    myWebService.BeginMyMethod(new MyRequest(), result, new AsyncCallback(callback), i);
    stopWatches[i].Start();
}
// Call back stop the stopwatch after calling EndMyMethod
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为所有请求(10000)具有相同的开始时间并且持续时间将线性上升(调用0 =持续时间1,调用1 =持续时间2等).如何使用异步方法监控呼叫的实际持续时间(从请求真正执行到结束的那一刻)?


更新:异步方法是否会阻止流程?我知道它使用.NET ThreadPool但是如何IAsyncResult知道调用已完成并且是时候调用该CallBack方法了?

zvo*_*kov 3

代码是铁路,线程是火车。当火车在铁路上行驶时,它会执行代码。

BeginMyMethod由主线程执行。如果您查看内部,BeginMyMethod它只是将一个委托添加MyMethod到 的队列中ThreadPool。实际MyMethod是由火车池的其中一列火车执行的。完成时调用的完成例程MyMethod由执行 的同一线程执行MyMethod,而不是由运行其余代码的主线程执行。当线程池线程忙于执行时MyMethod,主线程可以乘坐铁路系统的其他部分(执行其他代码),或者只是休眠,等待特定信号量点亮。

因此,不存在IAsyncResult“知道”何时调用完成例程之类的事情,相反,完成例程只是线程池的线程在执行完毕后立即调用的委托MyMethod

我希望您不要介意有点幼稚的火车比喻,我知道它在向人们解释多线程时不止一次帮助了我。