2013-02-18 105 views
4

我已经理解了异步等待的概念并一直使用它,但确实有一些关于最佳实践的问题。异步等待最佳实践

  1. 是它确定使用伺机在一段时间(条件)循环,以保持读取可能存在的数据,直到而病情变化,例如stopProcessingMessages = false。

  2. 在诸如winforms的应用程序中,UI在其上运行线程时,使用async/await等操作(如按钮单击)相当平凡,但如果我想要在整个控制台应用程序中异步执行,怎么办? ,甚至一个Windows服务。最初启动第一个等待任务的最佳实践是什么,那是Task.Run(()=> ...)?

我希望我在第二个问题中有意义。我想充分利用异步并充分利用它,但只需了解如何在启动异步操作之前启动异步操作,然后再开始执行所有其他异步功能。

道歉不使用正确的代码块我在火车上使用我的智能手机。

回答

7

我已经掌握了异步的概念等待,并偶尔用它了,但有关于最佳做法的一对夫妇的问题。

我有一个intro to async/await blog post比大多数介绍更详细,也介绍了几个最佳做法。

可以在while(condition)循环中使用await来继续提取可能存在的数据,直到while条件改变为止。 stopProcessingMessages = false。

你想避免紧密循环。所以while (condition) GetDataIfPresent();将消耗大量的CPU。

或者,您可以使用返回null(或其他)是否stopProcessingMessagestrue一个async方法。在这种情况下,您的代码将是while (true),而更类似TAP的解决方案将使用CancellationSource而不是标志。

也看看TPL Dataflow;这听起来像它可能对你的情况有用。

控制台应用程序,甚至是Windows服务。首先启动的第一个等待任务的最佳做法是什么

对于控制台应用程序,您可以在顶层任务上使用Wait。对于通常的指导原则(这是await而不是Wait)这是一个可接受的例外。 Wait ing将在控制台应用程序期间刻录线程,但这通常不足以保证更复杂的解决方案。如果您确实想为您的控制台应用程序安装单线程环境,则可以使用我的AsyncEx library中的AsyncContext.Run

对于Win32服务,您通常会使用do need to start your own thread。您可以使用Task.Run(如果需要多线程上下文)或AsyncContextThread(如果需要单线程上下文)。

+0

谢谢你简洁的回答斯蒂芬。我实际上最终选择了TPL Dataflow的BufferBlock。在控制台环境中,我还发现Task.Run(async()=> await ....);踢一个初始的异步过程也足够了。 – Sash 2013-02-21 22:22:14

+0

重新提供控制台顶级'async'动作:'Task.Run'不会简单地调用'async'方法。您仍然需要对返回的任务执行“等待”,等待它退出前完成。 – 2013-02-22 02:53:31

2

早上好,

我宁愿使用常规的任务,在你的比异步/ AWAIT模式第一个场景设置为“LongRunning”的TaskCreationOption。 通过这种方式,您的整个时间块将在一个长时间运行的任务中执行。当在每个while循环中使用await时,您将开始每个循环的新任务 - 可以工作,但可能不是那么理想;-)

关于第二个问题,我很抱歉,但我没有明白你的观点。

希望这会有所帮助。

+0

事实上,一个充满'await'的循环实际上会开始......多少个新任务?除非'stopProcessingMessages'变量被设置为匆忙,否则它有可能使数千个线程旋转。也就是说,“持续取得”甚至在问题背景下意味着什么?单个任务具有*一个*结果,而不是不断获取的数据流。 – Snixtor 2013-02-18 06:24:21

0

使用循环来保留可能存在的数据是不好的.. 你可以创建一个异步调用,在完成时自动调用一个回调方法..在这种情况下,将发生“等待”阶段在以最佳方式处理正在使用的OS的这种等待阶段的OS机制中。

看看这里为主体的进一步研究: http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx