在WCF方法中使用Task.WaitAll

时间:2014-03-30 13:45:16

标签: c# wcf parallel-processing task-parallel-library async-await

我有一个.NET 4.5.1 WCF服务,可以处理来自数千个用户将使用的应用程序的同步。我目前使用Task.WaitAll,如下所示,它工作正常,但我读到这很糟糕,可能会导致死锁等等。我相信我曾经尝试过,而且它没有工作,我不会回想起这些问题,因为我要再次回到这里审核,以确保我能做到这一点。我担心的是,在这种使用中是否需要和首选阻塞,WCF服务方法因此WaitAll似乎没有问题地工作。

我有大约十几种方法,每种方法都更新实体框架6中的实体,用现有数据处理传入数据并进行必要的更改。这些方法中的每一种都很昂贵,所以我想主要使用并行性来使所有方法在这个功能强大的24核服务器上同时工作。每个方法返回为Task,在Task.Run中包装其内容。 DoSync方法创建了一个新List,并将每个同步方法添加到列表中。然后我调用Task.WaitAll(taskList.ToArray()),一切都很棒。

这是正确的做法吗?我想确保此方法可以很好地扩展,不会导致问题,并在WCF服务方案中正常工作。

2 个答案:

答案 0 :(得分:5)

在高规模服务中,使用异步IO(您不是 - 使用Task.Run)通常是个好主意。 “高规模”的定义非常松散。异步IO在服务器上的好处是它不会阻塞线程。这导致更少的内存使用和更少的上下文切换。这就是它的全部内容。

如果您不需要这些好处,可以使用同步IO并阻止您喜欢的所有内容。什么都不会发生。明白,在后台线程上运行10个查询并等待它们将暂时阻塞11个线程。这可能没有问题,取决于您期望的并发操作数。

我建议您对async IO的可伸缩性优势进行一些研究,以便在使用它时更好地理解。请记住,异步会有成本:开发速度较慢,并发错误更多。

明白,异步IO与仅使用线程池(Task.Run)不同。线程池不是无线程的,而async IO根本不使用任何线程。甚至不是运行时管理的“不可见”线程。

我经常发现:如果你不得不问,你不需要它。

答案 1 :(得分:0)

Task.WhenAllTask.WaitAll的非阻止等价物,如果没有看到您的代码,我就无法想出为什么它不起作用而且不会更好。但请注意,Task.WhenAll本身会返回Task,您必须await。你做到了吗?