1

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

基本上,我想要一些东西,比如你在熟食店买票,然后等轮到你,然后他们再回来找你。我会试着把它联系起来,看看它是否有意义......

函数开始--->到达需要“取票”的部分(我假设在阻塞集合中排队某种类型的项目)并等待其他“票”(也就是同一函数的其他实例)在它之前完成使函数可以恢复(阻止集合到达队列中的项目)--->完成函数。

我不需要/不想在队列中做任何工作,我只想让函数在函数的其他实例中静态等待它轮到它。那有意义吗?那可能吗?

如果可能,请提供代码,因为我已经看到了大量的示例,但没有一个是有意义的/不要做我想做的。

4

2 回答 2

1

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

然而,我实际上推荐的是,您使用 SemaphoreSlim 类来限制对这个脆弱的 Web 服务的并发请求数。可能您应该选择一个介于 1 到 5 之间的数字作为允许的并发量。

于 2012-04-13T15:44:57.530 回答
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);
    }
}
于 2012-04-17T04:39:58.513 回答