【问题标题】:creating and terminating a thread contained in a collection创建和终止集合中包含的线程
【发布时间】:2011-10-20 10:53:26
【问题描述】:

我有一个自定义集合(一个线程安全的 ObservableQueue)。我在集合类中实现了业务逻辑(即将项目逐个出列并将它们暴露给外部)。这工作正常。为了防止集合阻塞初始化它的线程, OnservableQueue 实现了一个线程来执行该工作。现在我不能完全确定可能发生的任何陷阱。

在构造函数中初始化(不启动!仅初始化)线程是不是一个坏主意?如果不是最好的,终止线程的最佳实践是什么?请注意,我不需要知道如何终止线程,它工作正常,我对天气很感兴趣,使用一次性模式或创建需要调用以终止线程的方法有问题。如果实施IDisposable,关于收集/队列有什么需要考虑的吗?

编辑:线程实际上只是预先初始化以防止NullReferenceException被抛出入队列方法,在那里它被再次正确初始化(入队方法应该检查天气出队线程已经在运行,如果不启动一个新线程)。请注意,每当所有项目都出队并且线程完成其工作时,它也将不再处于活动状态,因此每当队列为空并添加新项目时,都会启动一个新线程来处理队列:

if (!_dequeuingThread.IsAlive)
{
    // start the dequeuing thread
    _dequeuingThread = new Thread(new ThreadStart(StartDequeuing));
    _dequeuingThread.Name = "DeQueueThread";
    _dequeuingThread.Start();
}

if 语句确实需要一个初始化的线程。还有其他可能的方法来实现这一点,但预初始化线程似乎最不麻烦。您会看到,在检查天气之后,线程还活着,在预初始化时它不应该这样做,它会再次正确初始化。

【问题讨论】:

    标签: c# .net multithreading collections disposable


    【解决方案1】:

    我看不出在构造函数中初始化有什么问题,但很明显,它们将在与您的工作线程不同的线程中初始化。

    至于停止,我通常有一个不稳定的布尔标志,工人检查它以保持运行。如果您的工作线程完全休眠,则让它等待事件而不是休眠,这样您就可以在停止时立即唤醒它。

    【讨论】:

    • 工作线程在一个紧密的循环中运行,迭代队列中的项目,使它们出队。在那个循环中,我检查了一个 volatile bool 的真值。它正在迭代循环或不存在。那么你实际上会在哪里设置标志呢?在方法中(StopDequeuing())或实现IDisposable
    • 个人两个。我有一个设置标志并等待工作线程退出的 StopDequeuing() 函数,并且我有一个名为 StopDequeuing() 的 Dispose() 实现。
    【解决方案2】:

    消费者将通过调用它的构造函数来初始化这个集合对象,并且它会认为这个对象已经被初始化(构造函数应该做的),这似乎是一个问题,这是不正确的,因为初始化发生在构造函数创建的单独线程上。所以,基本上你需要在这个对象上实现某种“异步 API”来初始化这个集合,以便消费者调用 initialize 方法(在使用构造函数创建对象之后),然后通过将回调传递给 initialize 方法或通过在集合对象上注册一个事件,消费者可以知道初始化已经完成。

    【讨论】:

    • 实际上线程只是在构造函数中初始化,这样以后对Thread.IsAlive的调用就不会抛出NullReferenceException。在实际线程启动之前,它将再次正确初始化——因为如果先前的出队线程已经完成其工作(并且不再存在),则需要这样做。除此之外,它是一个线程安全的 ObservableQueue,实现了INotifyCollectionChanged 接口和一个Dispatcher,因此它可以初始化并完美地更新它所绑定的任何内容:) 请参阅上面的编辑以了解线程是如何真正初始化的。
    猜你喜欢
    • 1970-01-01
    • 2022-06-12
    • 1970-01-01
    • 2011-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-18
    相关资源
    最近更新 更多