【发布时间】:2016-04-13 08:50:31
【问题描述】:
我认为它们基本上是一样的——编写在处理器之间分割任务的程序(在具有 2 个以上处理器的机器上)。然后我正在阅读this,上面写着:
异步方法旨在成为非阻塞操作。一个等待 异步方法中的表达式不会阻塞当前线程,而 等待的任务正在运行。相反,该表达式签署了其余部分 方法的延续并将控制权返回给调用者 异步方法。
async 和 await 关键字不会导致额外的线程 创建的。异步方法不需要多线程,因为异步 方法不在自己的线程上运行。该方法在当前运行 同步上下文并仅在线程上使用时间 方法处于活动状态。您可以使用 Task.Run 将 CPU 密集型工作移动到 后台线程,但后台线程对进程没有帮助 那只是在等待结果可用。
我想知道是否有人可以为我将其翻译成英文。它似乎区分了异步性(这是一个词吗?)和线程,并暗示您可以拥有一个具有异步任务但没有多线程的程序。
现在我了解了异步任务的概念,例如 pg 上的示例。 Jon Skeet 的 C# In Depth,第三版 467
async void DisplayWebsiteLength ( object sender, EventArgs e )
{
label.Text = "Fetching ...";
using ( HttpClient client = new HttpClient() )
{
Task<string> task = client.GetStringAsync("http://csharpindepth.com");
string text = await task;
label.Text = text.Length.ToString();
}
}
async 关键字的意思是“此函数,无论何时被调用,都不会在调用后的所有内容都需要完成的上下文中调用。” p>
换句话说,在某个任务的中间写它
int x = 5;
DisplayWebsiteLength();
double y = Math.Pow((double)x,2000.0);
,由于DisplayWebsiteLength()与x或y无关,将导致DisplayWebsiteLength()“在后台”执行,比如
processor 1 | processor 2
-------------------------------------------------------------------
int x = 5; | DisplayWebsiteLength()
double y = Math.Pow((double)x,2000.0); |
显然这是一个愚蠢的例子,但我是正确的还是我完全糊涂了还是什么?
(另外,我很困惑为什么 sender 和 e 从未在上述函数的主体中使用。)
【问题讨论】:
-
sender和e暗示这实际上是一个事件处理程序——几乎是唯一需要async void的地方。最有可能的是,这会在按钮单击或类似的情况下调用 - 结果是此操作相对于应用程序的其余部分完全异步发生。但它仍然都在一个线程上 - UI 线程(在将回调发布到 UI 线程的 IOCP 线程上有一小段时间)。 -
关于
DisplayWebsiteLength代码示例的一个非常重要的说明:您不应该在using语句中使用HttpClient- 在重负载下,代码可能会耗尽可用套接字的数量,从而导致SocketException 错误。有关Improper Instantiation 的更多信息。 -
@JakubLortz 我不知道这篇文章是写给谁的。不适合初学者,因为它需要对线程、中断、CPU 相关的东西等有很好的了解。不适合高级用户,因为他们已经很清楚了。我相信它不会帮助任何人理解它的全部含义 - 抽象级别太高。
标签: c# multithreading asynchronous parallel-processing async-await