【问题标题】:How do I terminate a worker thread when the owning object is collected?收集拥有对象时如何终止工作线程?
【发布时间】:2011-06-16 14:14:33
【问题描述】:

我有一个对象,它有一个BackgroundWorker 线程(纯粹是一个动作委托队列)。即,这是常见的、简单的单生产者单消费者场景。

当收集到单个生产者时,我希望它将终止操作排入BackgroundWorker 线程。

这听起来很简单——使用终结器——但这违反了“不要在终结器中触及托管资源”的规则。

那么,一旦没有更多工作要做,我如何确保线程干净地终止呢?

我不想接受的答案:

  • IDisposable:这将需要对基类进行大规模的重大更改,但我接受它可能是必需的(这似乎总是 IDisposable 模式的问题..)
  • ThreadPool:这些是长时间运行的操作,必须按顺序运行。因此,我认为专用线程是合乎逻辑的选择。
  • WeakReference:刚想到这个。也许这是正确的方法(?)。基本上,线程将WeakReference 保留给拥有的对象,并定期唤醒自己以检查WeakReference 是否还活着,当它死时它会排队终止。不太优雅 - 我不喜欢“定期唤醒自己”这一点 - 但这是最​​好的解决方案吗?

【问题讨论】:

    标签: c# multithreading garbage-collection finalizer


    【解决方案1】:

    IDisposable 或类似的东西听起来对我来说是最好的方法 - 明确说明您何时完成生产,而不是从垃圾收集中触发。

    从根本上说,问题不在于终止工作线程——这表明您已经完成了生产。我明白这在某些情况下可能会很棘手,但如果所有可能的话,如果你能明确地做到这一点,它会让你的生活更加可预测。

    【讨论】:

    • 谢谢乔恩,我想这是最好的方法。只是烦人的是实现IDisposable 的重大更改(尤其是对象的所有所有者都需要开始实现它..)-但我认为这确实是确定性关闭后台线程的唯一方法。叹息..我还有很多工作要做。
    • @Mania:你有我的同情。可能值得考虑重新组织其他任何事情是否会使这更容易处理。当您需要关闭生产者时,您是否有任何其他类型的事件被触发?
    • 并非如此。生产者的各种方法添加到后台线程的队列中(一段时间后更新值),因此一旦生产者的主要代码丢弃,后台线程不再具有存在的目的。所以从逻辑上讲 - 这个生产者应该实现 IDisposable。问题是基类和它的其他实现对后台线程没有同样的需求,所以我从来没有想过要实现 IDisposable。但我同意,这是一个值得做的改变。问候。
    猜你喜欢
    • 2012-05-27
    • 1970-01-01
    • 2014-02-02
    • 1970-01-01
    • 2011-09-30
    • 2013-07-02
    • 1970-01-01
    • 2011-10-27
    • 1970-01-01
    相关资源
    最近更新 更多