C# 仅当前一个线程完成时,才按启动顺序启动线程
很抱歉让人困惑的标题,但这基本上就是我需要的,我可以用全局变量做一些事情,但这只适用于一个接一个请求的两个线程 下面是一个伪代码,可以更好地解释它C# 仅当前一个线程完成时,才按启动顺序启动线程,c#,multithreading,C#,Multithreading,很抱歉让人困惑的标题,但这基本上就是我需要的,我可以用全局变量做一些事情,但这只适用于一个接一个请求的两个线程 下面是一个伪代码,可以更好地解释它 /*Async function that gets requests from a server*/ if ()//recieved request from server { new Thread(() => { //do st
/*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();
}
静态队列myQ=新队列();
静态void Main(字符串[]参数)
{
新线程(()=>
{
而(1==1)
{
if(myQ.FirstOrDefault()==null)
打破
myQ.FirstOrDefault().Invoke();
}
}).Start();
myQ.排队(()=>
{
TestQ(“第一”);
});
myQ.排队(()=>
{
TestQ(“第二”);
});
Console.ReadLine();
}
私有静态void TestQ(字符串s)
{
控制台。写入线(s);
睡眠(5000);
myQ.Dequeue();
}
我对代码进行了注释,我基本上需要检查act是否是队列中的第一个
编辑:所以我重新制作了它,现在它工作了,肯定有更好的方法来实现这一点吗?因为我不能使用无限while循环。您必须为线程使用全局容器。也许可以检查一下 此类将队列实现为循环数组。存储在 队列在一端插入,从另一端移除 当需要临时存储时,队列和堆栈非常有用 信息;也就是说,您可能希望在 检索其值。如果需要访问信息,请使用队列 与它在集合中的存储顺序相同。如果需要,请使用堆栈 您需要按相反的顺序访问信息。使用 ConcurrentQueue(共有) T) 或ConcurrentStack(共 T) 如果您需要访问 同时从多个线程创建集合 可以对队列及其元素执行三个主要操作:
- Enqueue将一个元素添加到队列的末尾
- “出列”从队列的开头移除最旧的元素
- 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);
}
静态队列myQ=新队列();
静态void Main(字符串[]参数)
{
myQ.排队(()=>
{
TestQ(“第一”);
});
myQ.排队(()=>
{
TestQ(“第二”);
});
线程线程=新线程(()=>
{
while(true){
线程。睡眠(5000)
如果(myQ.Count>0){
myQ.Dequeue().Invoke()
}
}
}).Start();
//做其他事情,最终调用“thread.Stop()”停止无限循环。
Console.ReadLine();
}
私有静态void TestQ(字符串s)
{
控制台。写入线(s);
}
如果当前有线程在运行,则可以将收到的请求放入。然后,为了找出线程何时返回,它们可以触发一个。当此事件激发时,如果队列中有内容,则启动一个新线程来处理此新请求
唯一需要注意的是,您必须小心,因为您基本上是在多个线程之间进行通信。所以您不需要多线程,这听起来更像是需要一个队列。@oerkelens,我想是吧?每次服务器向发送请求时,我都会启动一个线程,但我不希望这些线程并行执行。如果您逐个执行,则无需启动新线程。只需将请求排队并逐一处理即可。有几种方法可以实现排队,但我相信谷歌在这方面能帮上大忙:)如果我能提出一个建议,也许可以看看计算机科学中普遍存在的“生产者-消费者”问题。了解问题空间的领域可能会让你找到更多你感兴趣的东西。您忽略了最重要的部分:服务器如何与客户机通信,反之亦然?您已经完全掩盖了这一点,但是客户端排队在服务器上工作并获得结果的实际机制是困难的部分;编写一个生产者-消费者队列实现来服务队列中的内容是现成的部分。如果我需要立即执行请求,这将如何工作?看起来您需要排队,然后才启动它,或者我遗漏了什么?使用
Peek
查看第一个线程并验证它是否正在运行。如果它已停止且尚未完成,则启动它Dequeue
it如果它已经完成,则使用Peek
启动下一个。是的,你创建了一个线程,将其排队,然后验证第一个线程。米歇尔,我用我提出的一些代码编辑了我的帖子,以及我现在面临的问题:)@TricksterJoe我还有其他想法,但你有另一个可能的解决方案。只需创建一个全局队列
对象并向其添加操作。在线程中,执行无限循环并检查队列中是否有操作。如果有,获取操作(action myVar=myQueue.Dequeue()
)并对其进行操作。我不建议像你那样传递队列对象。谢谢你的输入,你能检查一下新编辑的版本吗?我将它设置为一个全局变量,用一个无限循环启动一个新线程,该循环调用队列中的第一个对象,它看起来就像预期的那样工作。