异步和异步方法澄清?

时间:2013-06-15 14:09:23

标签: .net task-parallel-library task async-await c#-5.0

AFAIK - (我读了很多关于它的),异步方法( 异步委托!)存在以解决“线程”阻止“处理 I / O操作时的问题:读取文件或下载文件:

Richter在这里非常清楚地表明了这一点:

enter image description here

  • Task<T>与i / o阻止问题无关。它就像打开一个线程(加上额外的效率+功能) - 但它仍然会导致一个线程消耗cpu quanta等。

这是我的问题:

我读过(msdn):

  

async 方法提供了一种方便的方法   长时间运行而不阻止调用者的线程。来电者   异步方法可以在不等待异步的情况下恢复其工作   方法完成。

  • 是否就像使用Task<t>创建ContinueWith一样?

  • 术语是否令人困惑? asynchronous methods用于i/o次操作(其中有线程等待进行i / o操作且没有线程正在处理它)。 将代码(使用异步)调用为:asynchronous methods有点令人困惑。你不觉得吗?因为我假设有另一个正在执行的线程......(这实际上是我的第一个问题)。

混淆来自哪里?

因为Albahari tend to emphasize是什么异步方法:

enter image description here

P.S。关于这个话题,我在SO上已经阅读了一些问题,但没有找到任何关于异步方法在这里处理io操作的错误分类的问题

2 个答案:

答案 0 :(得分:4)

  

Task<T>与I / O阻塞问题无关。它就像打开一个线程(加上额外的效率和功能) - 但它仍然会导致一个线程消耗CPU量子等。

不一定。基本上有两种Task:一种执行同步代码,并在代码完成执行时完成。这种Task自开始执行以来一直阻塞Thread直到它完成(成功与否)。

但还有另一种Task:一种在事情发生时完成的事情。这种Task是.Net 4.5和C#5.0大量使用而且它不会阻塞Thread(至少不是直接)。您可以使用Task自行创建此类TaskCompletionSource<T>

(另一点是被阻塞的线程不消耗任何CPU,但这在这里并不重要。)

  

就像使用Task<t>创建ContinueWith一样?

是的,await tt.ContinueWith(rest of the method)非常相似。

  

术语不是令人困惑吗?异步方法用于I / O操作(在进行I / O操作且没有线程处理它时,零线程等待)。但是要将代码(使用异步)调用为:异步方法有点令人困惑。你不觉得吗?因为我假设有另一个正在执行的线程。

我没有看到混乱。经典异步方法(如BeginRead();这称为“异步编程模型”或APM)是一种启动操作并在完成时通知的方式(通过回调)。现代异步方法(如ReadAsync();这称为“基于任务的异步模式”或TAP)也是一种启动操作并在完成时通知的方式(使用await)。

在这两种情况下,可能会有一些代码在方法返回之前执行(TAP案例中第一个await之前的代码)。

在这两种情况下,通常的结果通知方式都不会阻止任何线程(APM的回调,TAP的await)。

在这两种情况下,您可以根据需要使用阻塞等待(立即调用APM的EndXxx()方法,TAP为Wait())。

这两种情况都可用于在后台线程上执行同步代码(BeginInvoke()代表APM,Task.Factory.StartNew()代表TAP。“

同样,我没有看到混乱,这两个模型看起来与我很相似。

答案 1 :(得分:3)

异步方法对于IO来说不仅仅是 - 它们可以用于任何事情 - 是的,它只是另一种说法方法的工作在一个单独的线程中执行的方式。调用线程将工作卸载到单独线程的任何方法都可以正确地称为“异步”方法。它与Task<T>ContinueWith相同 - ContinueWith只是另一种谈论回调的方式。

“异步”一词仅表示“不在同一时间” - 它可以指任何彼此独立发生的行为。