2011-10-20 26 views
0

我有一個自定義集合(一個線程安全的ObservableQueue)。我在集合類中實現了業務邏輯(即將這些項目逐個出列並將它們暴露給外部)。這工作正常。爲了防止集合阻塞初始化的線程,OnservableQueue實現了一個線程來執行該工作。現在我不完全確定可能發生的任何缺陷。創建並終止集合中包含的線程

在構造函數中初始化(不是開始!只是初始化)線程是不是一個好主意?如果不是最好的,終止線程的做法是什麼?注意,我不需要知道如何終止一個線程,這是工作正常,我對天氣很感興趣,使用一次性模式或使用一次性模式創建一個方法需要調用來終止線程。如果實施IDisposable有什麼事情需要考慮收集/排隊?

編輯:線程實際上只是預先初始化爲防止NullReferenceException從排隊方法,它被正確地再次initilised被拋出(入隊的方法應該是檢查天氣出隊線程已如果運行不要開始新的)。請注意,無論何時出現所有項目並且線程已完成其工作,它將不再活動,因此,只要隊列爲空且添加了新項目,新線程就會開始處理隊列:

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

if語句確實需要初始化線程。還有其他可能的方法來實現這一點,但預先初始化線程似乎最不麻煩。你會發現,在檢查天氣線程是活着的之後,它在預初始化時不應該被使用,它會被正確地再次初始化。

回答

0

我沒有看到在構造函數中進行初始化時出現任何錯誤,但是顯然他們將在與您的工作線程不同的線程中初始化。

至於停止,我通常有一個易變的布爾標誌,工人檢查繼續運行。如果你的工作線程完全睡眠,那麼讓它等待事件而不是睡覺,所以你可以在停止時立即將它喚醒。

+0

工作線程在緊密循環中運行,遍歷隊列中的項目並將它們取出。在那個循環中,我檢查了volatile變量的真值。它正在迭代循環或不活着。那麼你會在哪裏設置標誌?在一個方法('StopDequeuing()')或實現'IDisposable'? –

+0

個人都有。我有一個StopDequeuing()函數來設置標誌並等待工作線程退出,並且我有一個名爲StopDequeuing()的Dispose()實現。 – GazTheDestroyer

0

似乎有一個問題,消費者會通過調用它的構造函數來初始化這個集合對象,並且它會認爲對象被初始化了(構造函數應該這樣做),這是不正確的初始化發生在由構造函數創建的單獨線程上。所以,基本上你需要在這個對象上實現某種「異步API」來初始化這個集合,這樣使用者就可以調用initialize方法(在使用構造函數創建對象之後),然後通過將回調傳遞給initialize方法或通過註冊集合對象上的事件,消費者可以知道初始化已完成。

+0

實際上,線程僅在構造函數中初始化,以便稍後調用「Thread.IsAlive」時不會拋出「NullReferenceException」。在實際線程_started_之前,它會再次正確初始化 - 因爲無論如何,如果先前的分離線程已完成其工作(並且不再活動),則需要這樣做。除此之外,它是一個線程安全的ObservableQueue,它實現了INotifyCollectionChanged接口和一個Dispatcher,所以它初始化OK並完全更新綁定到的任何東西:)參見上面關於線程是如何初始化的編輯。 –