2012-04-13 222 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