2013-05-28 121 views
1

我有一個事件觸發多次。每次射擊都會產生一個處理輸入的線程,並且這些處理必須是順序的。C#:管理線程等待隊列

這是代碼:

void TcpClient_DataRead(object sender, DataReadEventArgs e) 
    { 
     //the first stops the other ones 
     this.parsingXML.WaitOne(); 
     //processing the string 
     string pop = Encoding.ASCII.GetString(e.Data); 
     BufferizeXML(pop); 
     //restoring execution 
     this.parsingXML.Set(); 
    } 

在這裏,我試圖讓其他線程等待和前一個執行結束後恢復,但這種方法恢復所有的等待線程。

是否有一個管理等待線程隊列的方法?

+2

聽起來像一個可愛的TPL DataFlow工作:http://msdn.microsoft.com/en-us/library/hh228603.aspx – spender

回答

5

這是一個典型的情況,您可以使用發佈 - 消費者模式。 您可以使用Queue<T>ConcurrentQueue<T>排隊事件,然後讓一個線程出隊並執行實際處理。你只需要一個線程,因爲你說他們需要按順序執行,這將避免創建線程的時間。如果你不能(主要是因爲你被迫使用舊版本的框架)使用併發版本,那麼請注意你必須鎖定隊列訪問的事實。

+2

+1,是的,也避免了線程微觀管理,新手總是出錯,而那些有更多經驗的人從不嘗試。不幸的是,OP似乎已經閱讀了許多着名的「Introduction to Threads」書籍/網站,它們似乎總是以不斷創建線程並等待它們以join()或其他方式終止爲開始。正如我以前多次發表的那樣,這些作者應該與利害關係,他們的書籍/打印輸出堆放在一起,並使用火炬。 –

0

當應用程序初始化,創建併發隊列,啓動數據讀取任務並在其後綁定事件處理程序時啓動任務。

ConcurrentQueue<DataReadEventArgs> list; 
Init() 
{ 
    var list = new ConcurrentQueue<DataReadEventArgs>(); 
    Task.Factory.StartNew(()=>DataRead()); 
    OnTcpClientDataRead += TcpClient_DataRead; 
} 

//發佈

void TcpClient_DataRead(object sender, DataReadEventArgs e) 
{ 
    list.Enqueue(e); 
} 

一個始終運行的作業在隊列中的所有數據處理BufferizeXml,如果列表爲空它需要一秒鐘的暫停和再繼續//消費器

void DataRead() 
{ 
    while(true) 
    { 
    if (list.Count ==0) 
    Thread.Sleep(1000); 

    string pop; 
    list.TryDequeue(out pop); 
    Encoding.ASCII.GetString(pop); 
    BufferizeXML(pop); 
    } 
} 

你可以放一些變量,讓while循環檢查它是否打破迭代。

+0

如果TcpClient_DataRead被2個線程同時訪問會發生什麼?在這種情況下不會工作,您需要在開始時初始化它。 –

+1

@FelixK。我更改了代碼。 –