【问题标题】:Using Task.WaitAll in a WCF method在 WCF 方法中使用 Task.WaitAll
【发布时间】:2014-03-30 13:45:16
【问题描述】:

我有一个 .NET 4.5.1 WCF 服务,它处理来自成千上万用户使用的应用程序的同步。我目前使用 Task.WaitAll ,如下所示,它工作正常,但我读到这很糟糕,可能导致死锁等。我相信我过去尝试过WhenAll,但它没有用,我不记得问题是我将再次返回此进行审核,以确保我做对了。我担心的是在这种使用中是否需要和首选阻塞,这是一种 WCF 服务方法,因此为什么 WaitAll 似乎可以正常工作。

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

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

【问题讨论】:

  • 我知道这个问题很老了,但几乎没有理由在 WCF 服务中使用异步。对于并行性,您可以在其他情况下轻松使用 Parallel.For/Foreach 或 PLINQ .AsParallel()

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


【解决方案1】:

在大规模服务中,使用异步 IO 通常是个好主意(你不是——你使用Task.Run)。 “高比例”的定义非常松散。服务器上异步 IO 的好处是它不会阻塞线程。这导致更少的内存使用和更少的上下文切换。仅此而已。

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

我建议您对异步 IO 的可扩展性优势进行一些研究,以便您更好地了解何时使用它。请记住,异步是有代价的:开发速度较慢,并发错误更多。

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

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

【讨论】:

    【解决方案2】:

    Task.WhenAllTask.WaitAll 的非阻塞等价物,如果没有看到您的代码,我想不出任何原因为什么它不起作用并且不会更可取。但请注意Task.WhenAll 本身会返回一个Task,您必须使用await。你这样做了吗?

    【讨论】:

    • 您是否必须阻止 WCF 方法?服务上下文与 Http 上下文?不确定,我应该再试一次,但想看看这里对 WCF 使用的看法。谢谢
    • 没有。在await 之后似乎有一个issueOperationContext 为空,但如果你需要它,我会按照该链接中的简单建议并手动捕获它。比阻塞所有这些线程要好得多。
    猜你喜欢
    • 1970-01-01
    • 2019-06-17
    • 1970-01-01
    • 2021-09-17
    • 1970-01-01
    • 2018-04-15
    • 2011-07-26
    • 1970-01-01
    • 2017-08-21
    相关资源
    最近更新 更多