2

我可以看到新的 async 和 await 关键字在 GUI 应用程序中的用处,在这些应用程序中添加一个线程来进行一些计算是必要的,而且新的关键字真的很容易。但是其他类型的应用程序呢?

例如,执行某些工作的服务器或不断处理数据的进程?可能我仍然误解了新关键字,但是这些类型的应用程序是否会从新关键字中受益,或者我们是否应该继续使用 Tasks 来实现更明确的多线程?

4

5 回答 5

2

在非 GUI 应用程序中,使用的主要优点await是在执行 I/O 时。

如果您使用“旧方式”进行操作,您将使用同步方法进行 I/O,这会在线程工作时阻塞线程。使用await,您不会阻塞线程,这意味着您的应用程序将使用更少的线程,这可能会导致内存使用量大大降低(每个线程需要 1 MB 内存)和整体更好的性能。

您可以使用旧的异步编程模型实现类似的改进,但它要麻烦得多。

如果您不在乎您的非 GUI 应用程序使用的线程多于必要的线程,那么await对您来说没有太多用处。但是,如果您确实关心这一点,await则可以为您提供很多帮助。

于 2012-08-14T22:30:49.283 回答
1

await并且async是任务的补充

您仍然应该使用任务,但使用awaitasync与它们一起使用只会使异步方法的编写更容易。

于 2012-08-14T20:13:48.100 回答
1

例如,执行某些工作的服务器或不断处理数据的进程?

这在这里非常合适。例如,在 WCF 服务中,您可以使用 async 和 await 在单个异步请求中组合多个异步服务请求而不会阻塞。

可能我仍然误解了新关键字,但是这些类型的应用程序是否会从新关键字中受益,或者我们是否应该继续使用 Tasks 来实现更明确的多线程?

两人合作,非常好。Async 和 await 通常使使用和组合多个操作Task变得Task<T>更简单。

但是,在“最低级别”,创建实际值的代码Task可能会使用相同的基于 TPL 的技术来实现。一旦你有了创建 a Task、 async 和 await的方法,使用该方法(包括使用它来创建更多异步方法,或者使用它来创建同时运行多个任务的方法)就简单多了。

于 2012-08-14T20:17:10.673 回答
1

任何时候你计划调用一个最终会异步运行的方法,没有阻塞,并且你将有一个回调方法,你可以使用新的关键字来简化语法。如果您没有任何回调代码并且没有遵循延续传递的编程风格,那么新的关键字可能对您没有帮助。(这并不是说如果你真的......真的想使用它们,你就不能使用它们。)

于 2012-08-14T20:17:19.533 回答
0

例如,执行某些工作的服务器或不断处理数据的进程?可能我仍然对新关键字有误解,但是这些类型的应用程序是否会从新关键字中受益,或者我们是否应该继续使用 Tasks 来实现更明确的多线程?

几个月前,当我第一次开始使用 TAP 时,我也遇到了同样的问题,并得出结论认为 TAP 可以在并发的“类似服务器”的场景中很好地工作,而不必“陷入”一些更具体的问题TPL 的领域等。

例如,我目前正在处理的应用程序(它是一个 GUI 应用程序,顺便说一句,它也使用 TAP 来释放 GUI 线程)需要使用 SSH 与相当多的外部机器重复通信。想象一个大循环,其中应用程序需要 a) 向每个外部机器发送一个“命令”文件,b) 不久之后,轮询所有外部机器以获取“进度”文件(即使用 SSH 尝试下载文件) , c) 不久之后,轮询所有这些机器以获取“完成”文件等;这些步骤一遍又一遍地重复,直到我们“完成”。

在这个应用程序的第一次编写中,所有这些 SSH i/o 都是同步完成的,完成每个步骤的累积时间太长了。更不用说它不能很好地扩展,因为我们要求该应用程序支持更多的外部机器。

我已经重写了这个应用程序以同时执行每个步骤(a、b、c,如上所述)。因此,例如,向所有外部机器发送命令文件或多或少是同时发生的,而不是一个接一个地进行,从而允许应用程序在这些步骤(a、b、c)之间移动得更快、更流畅随着我们添加更多的外部机器,退化更少。

我通过 Task.Run() 开始每个 ssh 操作,因为我正在使用的 SSH 库本身不提供“异步”功能(但该库是线程安全的),然后我用 'await Task. WhenAll(任务列表)'。完成后,我会检查每项任务以查看结果,并据此进行。

除了使用 TAP 使这一切在代码中变得非常容易理解和令人愉悦之外,我还使用它对取消和进度对象的支持来处理取消并向用户报告这些活动的进度。

到目前为止,这工作得很好,我不必在 TPL 中进行任何比这更“深入”的操作,等等。有些人提到,当您获得“高度并发”时,您可能必须深入到 TPL 中,但我还没有亲眼看到“为什么”呢..

所以我想说,不要根据应用程序的“类型”(gui、服务器等)来确定 TAP 的有用性,而是根据您需要在应用程序中执行的活动的性质来确定;如果您需要同时进行多个计算,TAP 会很棒。如果您有很多需要同时完成的 i/o,TAP 会很棒。我们都知道使用 TAP 释放 GUI 线程的典型示例。

于 2012-08-28T15:54:00.867 回答