2

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

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

在此处输入图像描述

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

这是我的问题:

我读过(msdn):

异步方法提供了一种方便的方法来完成可能长时间运行的工作,而不会阻塞调用者的线程。异步方法的调用者无需等待异步方法完成即可恢复其工作。

  • 它就像创建一个Task<t>withContinueWith吗?

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

哪里来的混乱?

因为Albahari 倾向于强调异步方法的用途:

在此处输入图像描述

ps我在SO上阅读了一些关于这个主题的问题,但没有发现任何关于异步方法在这里处理io操作的错误分类

4

2 回答 2

4

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

不必要。基本上有两种Tasks:一种执行一段同步的代码,并在该代码执行完毕时完成。这种从开始执行到完成(成功与否)的整个时间都会Task阻塞。Thread

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

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

它就像创建一个Task<t>withContinueWith吗?

是的,await tt.ContinueWith(rest of the method).

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

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

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

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

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

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

同样,我没有看到混淆,这两个模型似乎与我非常相似。

于 2013-06-15T15:56:23.527 回答
3

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

“异步”这个词只是意味着“不同时” ——它可以指任何彼此独立发生的动作。

于 2013-06-15T14:32:12.943 回答