只有当前一个线程完成时,才按启动顺序启动线程

时间:2017-11-07 23:28:30

标签: c# multithreading

很抱歉令人困惑的标题,但这基本上是我需要的,我可以用全局变量做一些事情,但这对于一个接一个请求的2个线程是可行的。

这是一个伪代码,可以更好地解释它。

 /*Async function that gets requests from a server*/
        if ()//recieved request from server
        {
            new Thread(() =>
            {
                //do stuff
                //in the meantime a new thread has been requested from server
                //and another one 10 seconds later.. etc.

                //wait for this current thread to finish
                //fire up the first thread that was requested while this ongoing thread
                //after the second thread is finished fire up the third thread that was requested 10 seconds after this thread
                //etc...
            }).Start();
        }

我不知道何时会请求每个线程,因为它基于服务器向客户端发送信息,因此我无法执行Task.ContiuneWith,因为它是动态的。

所以迈克尔建议我调查队列,然后我想出来了

    static Queue<Action> myQ = new Queue<Action>();
    static void Main(string[] args)
    {
        new Thread(() =>
       {
           while (1 == 1)
           {
               if (myQ.FirstOrDefault() == null)
                   break;
               myQ.FirstOrDefault().Invoke();
           }
       }).Start();

        myQ.Enqueue(() =>
        {
            TestQ("First");
        });
        myQ.Enqueue(() =>
        {
            TestQ("Second");
        });
        Console.ReadLine();
    }
    private static void TestQ(string s)
    {
        Console.WriteLine(s);  
        Thread.Sleep(5000);
        myQ.Dequeue();
    }

我对代码进行了评论,我基本上需要检查该行为是否排在队列中。

编辑:所以我重新制作它,现在它可以工作,肯定有更好的方法来做到这一点?因为我无法使用无限循环。

2 个答案:

答案 0 :(得分:2)

您必须为线程使用全局容器。也许检查Queues

  

此类将队列实现为循环数组。存储在一个对象中   队列插入一端并从另一端移除。

     

当您需要临时存储时,队列和堆栈非常有用   信息;也就是说,当你想要丢弃一个元素之后   检索它的价值。如果需要访问信息,请使用队列   与存储在集合中的顺序相同。使用Stack if   您需要以相反的顺序访问信息。使用   如果您需要访问,则ConcurrentQueue(Of T)或ConcurrentStack(Of T)   同时从多个线程收集。

     

可以对Queue及其元素执行三个主要操作:

     
      
  • Enqueue将一个元素添加到队列的末尾。
  •   
  • Dequeue从队列的开头删除最旧的元素。
  •   
  • Peek返回队列开头的最旧元素,但不会将其从队列中删除。
  •   

编辑(从您添加的内容) 以下是我将如何更改示例代码以实现无限循环并将​​其保持在您的控制之下。

static Queue<Action> myQ = new Queue<Action>();
static void Main(string[] args)
{ 
    myQ.Enqueue(() =>
    {
        TestQ("First");
    });
    myQ.Enqueue(() =>
    {
        TestQ("Second");
    });
    Thread thread = new Thread(() =>
    {                             
        while(true) {
            Thread.Sleep(5000)
            if (myQ.Count > 0) {
                myQ.Dequeue().Invoke()
            }
        }
    }).Start();
    // Do other stuff, eventually calling "thread.Stop()" the stop the infinite loop.
    Console.ReadLine();
}
private static void TestQ(string s)
{
    Console.WriteLine(s);
}

答案 1 :(得分:2)

如果当前正在运行某个主题,您可以将收到的请求放入considered as returning an int。然后,为了找出线程何时返回,它们可以触发queue。当此事件触发时,如果队列中有某些内容,则启动一个新线程来处理此新请求。

唯一的问题是你必须要小心event,因为你基本上是在多个线程之间进行通信。