【问题标题】:Schedule a task from a short-lived thread从短期线程调度任务
【发布时间】:2012-09-18 10:49:03
【问题描述】:

我是 C# 新手,来自 C++,想问一下这是否是使用任务并行库的正确方法。

我有一个 Web 服务,它对长时间运行的操作进行排队。我不想使用异步网络调用,所以我的想法是使用 TPL,在调用网络操作时创建一个任务。我想知道如果我从一个在 Web 操作完成后立即终止的线程安排任务,是否存在任何类型的资源泄漏。假设我不会保留对任务的引用,因为我不需要检查它的状态或结果。谢谢。

编辑: 不好意思,第一枪没表达清楚。我的问题与网络服务有关,与客户无关。客户端调用需要很长时间的 Web 服务操作。 Web 服务调用返回说操作已在后台成功排队/执行。在Web服务操作中,我想使用TPL,而不是存储StartNew返回的任务对象。想知道,如果我不读取任务对象的状态并因此泄漏,是否会永远保留任务对象。也许这只是我的 C++ 思想阻碍了我,因为它是托管代码,所以我不应该关心泄漏。

【问题讨论】:

  • 我想知道为什么您不想使用异步 Web 调用,同时又想知道您创建的用于进行 Web 调用的任务会导致资源泄漏。也许我误解了这个问题;但听起来你想从另一个线程创建一个任务来执行一些网络调用。如果资源泄漏是一个问题并且这是您想要做的,那么当您具有出色的异步 IO 能力时,为什么要“泄漏”一个仅等待高延迟 IO 的线程?
  • 听起来您想将操作排队并在后台执行它们(可能是通过双向 WCF 服务或 some.pilling 机制)。我不认为 TPL 适合整个场景。一是您可能需要一个可靠的队列,这意味着某种程度的持久性。我会建议一些现成的队列。如果你这样做了,那么队列将处理线程来执行操作以及负载平衡等。
  • 但是如果我使用 TPL,排队和执行几乎是隐藏的,这是我理解的 TPL 的要点之一。无论如何,它在下面使用 ThreadPool。该操作仅在完成时更新数据库中的状态,因此我认为不需要使用双工 WCF 通信。在我的情况下也不需要持久队列,因为可以在 Web 服务启动期间使用 TPL 启动操作,当它从数据库构建其状态时。我只是担心如果启动任务、忘记任务对象并退出在任务完成之前启动任务的线程会导致任何 TFL 故障
  • 您认为 TPL 的队列是做什么的?它在某些地方进行一定的负载平衡;但它并没有真正做任何“排队”。例如如果你“启动”长时间运行的任务,没有什么能阻止 TPL 同时运行它们。您可以使用延续;但这真的很难动态地(即在运行时)。例如如何告诉 task2 在 task1 之后继续,而不会遇到 task1 在继续之前完成的竞争条件...
  • 忘记任务不会导致 TPL 出现任何问题,请参阅stackoverflow.com/questions/3734280/… 了解更多详细信息。但是,您希望在该任务中完成的工作很重要——如果您“忘记它”,您将如何知道它已经完成、正确完成并且不需要重新开始?这都是特定于应用程序的。

标签: c# task-parallel-library


【解决方案1】:

忘记任务不会导致 TPL 出现任何问题,请参阅 stackoverflow.com/questions/3734280/... 了解更多详细信息。但是,你想在该任务中做的工作很重要——如果你“忘记它”,你怎么知道它已经完成、正确完成并且不需要重新开始?这都是特定于应用程序的。

线程池的“完全忙碌”意味着已经创建并正在执行 1023 个线程池线程(这可能非常糟糕)。否则,线程池开始时每个 CPU/核心至少有一个线程,只要没有非运行线程的数量,就会通过每秒启动一个新线程来保持该最小值。所以,它真的不会“排队”任何东西。例如您可以启动 12 个任务,然后它“排队”4 个,在另一个点它运行所有 12 个......

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-20
    • 1970-01-01
    • 2021-02-09
    • 2019-05-30
    • 2019-05-18
    相关资源
    最近更新 更多