Abr*_*sef 18 .net c# asp.net task-parallel-library async-await
在我阅读.Net 4.5中的异步编程async
和await
关键字时,我在这里阅读以下段落
处理异步请求
在启动时看到大量并发请求或具有突发性负载(并发性突然增加)的Web应用程序中,使这些Web服务调用异步将提高应用程序的响应能力.异步请求与同步请求相同的处理时间.例如,如果请求进行需要两秒钟才能完成的Web服务调用,则无论是同步执行还是异步执行,请求都需要两秒钟.但是,在异步调用期间,在等待第一个请求完成时,不阻止线程响应其他请求.因此,当有许多并发请求调用长时间运行的操作时,异步请求会阻止请求排队和线程池增长.
对于粗体字,我无法理解异步请求如何像同步请求一样处理相同的时间?
例如:
public async Task MyMethod()
{
Task<int> longRunningTask = LongRunningOperation();
//indeed you can do independent to the int result work here
//and now we call await on the task
int result = await longRunningTask;
//use the result
Console.WriteLine(result);
}
public async Task<int> LongRunningOperation() // assume we return an int from this long running operation
{
await Task.Delay(1000); //1 seconds delay
return 1;
}
Run Code Online (Sandbox Code Playgroud)
我所理解的是LongRunningOperation()
从第一行调用开始执行并在调用后Task<int> longRunningTask = LongRunningOperation();
返回值await
,所以从我的观点来看,异步代码比同步更快,是吗?
我理解的是,正在执行的主线程MyMethod()
没有阻塞等待LongRunningOperation()
完成,但它返回到线程池以提供另一个请求.那么是否有另一个线程分配LongRunningOperation();
来执行它?
如果是,那么异步编程和多线程编程之间有什么区别?
更新:
让我们说代码变成这样:
public async Task MyMethod()
{
Task<int> longRunningTask = LongRunningOperation();
//indeed you can do independent to the int result work here
DoIndependentWork();
//and now we call await on the task
int result = await longRunningTask;
//use the result
Console.WriteLine(result);
}
public async Task<int> LongRunningOperation() // assume we return an int from this long running operation
{
DoSomeWorkNeedsExecution();
await Task.Delay(1000); //1 seconds delay
return 1;
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,LongRunningOperation()
执行期间DoIndependentWork()
是否会被另一个线程执行?
i3a*_*non 22
异步操作并不快.如果异步(即await Task.Delay(10000)
)或同步(即Thread.Sleep(10000)
)等待10秒,则需要10秒钟.唯一的区别是,第一个不会在等待时保持一个线程但第二个会保持一个线程.
现在,如果您启动任务并且不等待它立即完成,您可以使用相同的线程来执行其他工作,但它不会"加速"异步操作的运行:
var task = Task.Delay(10000);
// processing
await task; // will complete only after 10 seconds
Run Code Online (Sandbox Code Playgroud)
关于你的第二个问题:( Task.Delay
像其他真正的异步操作一样)不需要执行一个线程,因此没有线程.Task.Delay
使用System.Threading.Timer
你启动它来实现它并在它完成时引发一个事件,同时它不需要一个线程,因为没有代码可以执行.
因此,当正在运行的线程MyMethod
到达时,await longRunningTask
它被释放(只要longRunningTask
还没有完成).如果它是一个ThreadPool
线程,它将返回到ThreadPool
它可以处理应用程序中的其他代码的位置.
关于更新,流程将如此:
MyMethod
开始处理LongRunningOperation
开始处理DoSomeWorkNeedsExecution
在调用线程上执行await
是达到了LongRunningOperation
,因此返回一个热点课题.DoIndependentWork
由同一个调用线程执行(LongRunningOperation
仍在"运行",不需要线程)await
在到达MyMethod
.如果原始任务完成同一个线程将同步进行,如果没有,那么将返回最终完成的热任务.因此,您正在使用的事实async-await
允许您使用一个线程,否则该线程将被阻止同步执行CPU密集型工作.
考虑以下区别:
Thread.Sleep(1000);
Run Code Online (Sandbox Code Playgroud)
和
await Task.Delay(1000);
Run Code Online (Sandbox Code Playgroud)
两者都需要一秒钟才能运行.但是在前一种情况下,当前线程将被阻塞(并且其所有资源都无用),而在后一种情况下,当前线程可以执行其他有用的操作(例如,提供另一个请求).
异步性不是关于加速单个指令序列,而是能够在同步代码阻塞时执行操作.
回覆.另一个问题
释放的线程将用于其他事情; 在操作完成之前不会分配线程.这是可能的,因为底层操作系统本身是异步的.在上面的示例中,使用了一个计时器,该计时器通知线程在线程空闲时获取,而不是为内部停止的线程.
归档时间: |
|
查看次数: |
40589 次 |
最近记录: |