使用TPL和异步模式的实际区别

3

我正在研究使用长时间运行操作的两种方法之一。

我不会详细介绍每种方法可以完成什么,但我更想解释我想做什么。

我有一组HTTP相关的方法,每个方法都检索几个信息片段。这是长时间运行服务内部更大系统的一部分(因此它不是一些一次性的、可丢弃的代码)。

通常情况下,从封装和可维护性的角度来看,哪种方法更好:使用Begin/End/AsyncCallback机制在返回数据就绪时处理返回的数据,还是通过从任务中触发事件(如OnXXXReceived、OnXXXError),为每个事件使用派生的EventArgs类?

我希望我表述得足够清楚...我决定不提供代码示例,因为我更关心意见、建议和可能的陷阱,而不是具体实现的细节。

谢谢!

3个回答

2

一般来说,TPL任务更容易使用。在您的情况下,可以使用工厂和LongRunning选项创建它们。

但是我对事件不太确定。为什么不在循环或类似的东西中处理请求/响应呢?您已经在一个线程上了。


主要是因为从封装的角度来看,这些操作并不知道在检索数据后应该如何处理数据。它是外部范围的代码知道如何处理...但是,实际上,你可能是对的。我正在考虑将任务放入执行HTTP方法的类中,因此从外部代码中我将订阅事件,然后调用内部启动检索信息的任务的方法,并触发正确的事件。没有想到将任务放入外部范围以直接处理返回的数据。 - mr.b

1

你还可以使用ContinuationTasks在获取任务完成后处理数据。

    Task<StockDataCollection> loadFedHistoricalData =
        Task<StockDataCollection>.Factory.StartNew(
            () => LoadFedHistoricalData(),
            TaskCreationOptions.LongRunning);

    Task<StockDataCollection> normalizeHistoricalData =
        loadFedHistoricalData.ContinueWith(
            (t) => NormalizeData(t.Result));

在这段代码中,loadFedHistoricalData任务运行LoadFedHistoricalData,这是一个长时间运行的I/O绑定任务。当它返回时,它会继续另一个任务来规范化数据。 ContinueWith接受TaskContinuationOptions参数,可以用来指定连续任务是否总是运行,或者只有在满足某些条件(如错误或取消)时才运行。
第5章A-Dash示例展示了这种替代事件处理方法。您可以从http://parallelpatterns.codeplex.com/下载代码。查看AnalysisEngine和MainWindowViewModel类。

1

当涉及到I/O性能时,异步编程模型(APM)是无可匹敌的。只要可以使用它,就应该使用。幸运的是,任务并行库(TPL)内置了对通过FromAsync工厂方法将APM工作与“纯”TPL任务相结合的支持。

请查看MSDN上标题为TPL和传统.NET异步编程的.NET SDK的此部分,以获取有关如何将这两种编程模型组合以实现异步nirvana的更多信息。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接