2013-03-18 87 views
2

我正在處理包含ID作爲鍵和隊列作爲值的字典。我有一個線程寫入隊列,另一個線程讀取隊列,所以我需要使用.NET 4.0中引入的併發結構。作爲這個的一部分,我試圖編寫一個測試應用程序來填補隊列,但是我遇到了一個問題,計時器在大約10秒後停止。我真的不明白爲什麼,因爲沒有什麼可以抓到,沒有任何錯誤信息或任何事情給我一個關於什麼可能是錯誤的暗示。Threading.Timer在控制檯應用程序中停止

那麼有人可以向我解釋爲什麼計時器在大約10秒後停止?我已經在兩臺不同的計算機上嘗試了這種方式(都使用Visual Studio 2012,但使用.NET Framework 4.0)。

class Program { 

    private readonly ConcurrentDictionary<int, ConcurrentQueue<TestObject>> _pipes = 
     new ConcurrentDictionary<int, ConcurrentQueue<TestObject>>(); 

    static void Main() { 
     Program program = new Program(); 
     program.Run(); 
     Console.Read(); 
    } 

    private void Run() { 
     _pipes[100] = new ConcurrentQueue<TestObject>(); 
     _pipes[200] = new ConcurrentQueue<TestObject>(); 
     _pipes[300] = new ConcurrentQueue<TestObject>(); 

     Timer timer = new Timer(WriteStuff, null, 0, 100); 
    } 

    private void WriteStuff(object sender) { 
     for (int i = 0; i < 5; i++) { 
      foreach (KeyValuePair<int, ConcurrentQueue<TestObject>> pipe in _pipes) { 
       pipe.Value.Enqueue(
        new TestObject { Name = DateTime.Now.ToString("o") + "-" + i }); 
      } 
      i++; 
     } 
     Console.WriteLine(DateTime.Now + "added stuff"); 
    } 
} 

internal class TestObject { 
    public string Name { get; set; } 
    public bool Sent { get; set; } 
} 

回答

4

最有可能的是,計時器超出範圍並被收集。在外部範圍聲明計時器。那就是:

private Timer timer; 
private void Run() 
{ 
    ... 
    timer = new Timer(WriteStuff, null, 0, 100); 
} 

另外,我想你會發現,BlockingCollection是更容易使用比ConcurrentQueueBlockingCollection在併發集合周圍包裝了一個非常漂亮的API,在刪除事物時更容易在隊列上執行非繁忙的等待。在其默認配置中,它使用ConcurrentQueue作爲後備存儲。您只需使用代碼ConcurrentQueue替換BlockingCollection,然後將Enqueue更改爲調用Add。如在:

相關問題