带有计时器c#的静态FIFO队列

时间:2012-04-13 15:39:20

标签: c# multithreading

我有一个.NET 4.0 ASP.NET项目,需要一些我以前从未真正搞过的线程工作,我已经看了好几天了,我仍然无能为力= /

基本上我想要的东西就像你在熟食店买票并在他们回到你身边之前轮到你。我会试着把它联系起来,看看它是否有意义......

功能开始--->到达需要“获取票证”的部分(我假设在阻塞集合中排队某种类型的项目)并等待直到其他“票证”(也称为同一函数的其他实例)完成之后才能将该函数设置为OK resume(阻塞集合到达队列中的项目)--->完成功能。

我不需要/想要在队列中做任何工作,我只是希望函数静态地等待它在函数的其他实例之间转动。那有意义吗?那可能吗?

如果可能的话请提供代码,因为我已经看过很多例子,但没有一个有意义/没有做我想要的。

2 个答案:

答案 0 :(得分:1)

如果你想拥有计时器解决方案,我会将所有操作排入BlockingCollection并让一个专用线程将它们排队。该线程将等待5秒,然后将出队的项目推送到线程池。这个专用线程应该在无限循环中执行此操作。出道,等等,推。

我实际建议的是,您使用SemaphoreSlim类来限制对此脆弱Web服务的并发请求数。可能你应该选择1到5之间的数字作为允许的并发数量。

答案 1 :(得分:0)

好吧,所以在研究了文档之后的文档并玩了大量的代码重写后,我终于想通了我没有使用AutoResetEvent权限以及如何在专用线程上使用阻塞集合。所以这是使用带有BlockingCollection的AutoResetEvent的最终解决方案。下面的解决方案可能不会在100%的时间内显示相同的结果(仅仅因为我认为它与某些东西输入阻塞集合时的线程计时有关),但最终结果是它完全符合我的要求。 / p>

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);
    }
}