2012-04-13 196 views
1

我有一個.NET 4.0 ASP.NET項目,需要一些線程工作,我從來沒有真正搞砸了,我一直在看這個好幾天,我仍然無能=//靜態FIFO隊列與計時器c#

基本上我想要的東西就像當你在熟食店買票時等待輪到你回來給你。我會嘗試和這個關聯,看看它是否有任何意義...

函數啓動--->獲取到它需要「採取票」的部分(我假設隊列某種類型的項目在阻止集合中)並等待,直到其他「門票」(又名其他相同功能的實例)完成之後,纔會使功能恢復正常(阻止集合進入隊列中的項目)--->完成功能。

我不需要/希望在隊列中做任何工作,我只是希望函數靜態等待函數的其他實例之間的輪流。那有意義嗎?那可能嗎?

如果可能,請提供代碼,因爲我已經看過很多例子,但沒有一個是有意義的/不做我想做的。

+0

好了所以看完之後一些我絕對認爲BlockingCollection似乎是最好的主意,雖然我看不到的方式以這樣的方式來使用它只是返回回生產者類一旦該項目是排隊等待特定的線程出列。也許是AutoResetEvent.WaitOne的一些問題? – ElementZero 2012-04-15 02:18:20

回答

0

好吧,經過研究文檔和大量重寫代碼後,我終於明白我沒有使用AutoResetEvent的權利,以及如何在專用線程上使用阻塞集合。所以這裏是使用帶有BlockingCollection的AutoResetEvent的最終解決方案。下面的解決方案可能不會在100%的時間內顯示相同的結果(僅僅因爲我相信它與進入阻塞集合時的線程計時有關),但最終的結果是它完全符合我的要求。

class Program 
{ 
    static void Main(string[] args) 
    { 
     TaskProcessor tp = new TaskProcessor(); 

     Thread t1 = new Thread(new ParameterizedThreadStart(tp.SubmitRequest)); 
     t1.Start(1); 

     Thread t2 = new Thread(new ParameterizedThreadStart(tp.SubmitRequest)); 
     t2.Start(2); 

     Thread t3 = new Thread(new ParameterizedThreadStart(tp.SubmitRequest)); 
     t3.Start(3);   
    } 
} 

class TaskProcessor 
{ 
    private AutoResetEvent _Ticket; 

    public TaskProcessor() 
    { 
     _Continue = new AutoResetEvent(false); 
    } 

    public void SubmitRequest(object i) 
    { 
     TicketingQueue dt = new TicketingQueue(); 

     Console.WriteLine("Grab ticket for customer {0}", (int)i); 

     dt.GrabTicket(_Ticket); 

     _Continue.WaitOne(); 

     Console.WriteLine("Customer {0}'s turn", (int)i); 
    } 
} 

public class TicketingQueue 
{ 
    private static BlockingCollection<AutoResetEvent> tickets = new BlockingCollection<AutoResetEvent>(); 

    static TicketingQueue() 
    { 
     var thread = new Thread(
     () => 
      { 
       while (true) 
       {      
        AutoResetEvent e = tickets.Take(); 
        e.Set(); 
        Thread.Sleep(1000); 
       } 
      }); 
     thread.Start(); 
    } 

    public void GrabTicket(AutoResetEvent e) 
    { 
     tickets.Add(e); 
    } 
} 
1

如果你想擁有定時器解決方案,我會將所有操作排入BlockingCollection並讓專用線程將它們排隊。該線程將等待5秒,然後將出列項目推送到線程池。這個專用線程應該在無限循環中做到這一點。出隊,等待,推送。

然而,我真正推薦的是,你使用SemaphoreSlim類來限制併發請求這個脆弱的Web服務的數量。可能你應該選擇1到5之間的數字作爲允許的併發量。

+0

是的,我看到在這裏的專用線程使用阻塞解決方案 http://stackoverflow.com/questions/9811365/conditionally-run-the-methods-of-a-class-on-a-separate-thread但我沒有如何做到同步 – ElementZero 2012-04-13 16:20:03

+2

我明白。您希望IO的發行者等待IO完成。您可以通過創建與IO請求一起排隊的ManualResetEventSlim來完成此操作。一旦IO完成(在線程池上),它需要設置這個事件。 IO的原始發行者可以在該事件上等待()。所有這些溝通都以犧牲性能爲代價,但由於我們談論的是每秒一位數的請求,所以根本無關緊要。 – usr 2012-04-13 16:24:04