我有一个对象“代码”的列表:
List<Code> listCodes = new List<Code>();
我需要在Thread中执行列表中的每个代码,但我不知道如何做到这一点,因为我尝试做类似的事情:
foreach(Code c in listCodes)
{
Thread tr = new Thread(delegate() {
Execute(c.CodeLine);
});
}
这个foreach在一个计时器中,因为这些代码将一直执行,但是当我这样做时,即使第一次执行没有完成,相同的代码执行很多次,如果代码采用5要执行和完成的秒数,定时器为500毫秒,如果我在5秒后禁用定时器,则执行10次。
我想不出任何事情来执行列表中的代码,每个代码都在他们的线程中,但我想执行代码0的线程(例如)只有在执行后才完成。
谢谢。
答案 0 :(得分:4)
System.Threading.Monitor.TryEnter
非常适合这项工作:
foreach(Code c in listCodes) {
Code a = c;
new Thread(delegate() {
if(Monitor.TryEnter(a)) {
Execute(a.CodeLine);
Monitor.Exit(a);
}
}) { IsBackground = true }.Start();
}
它的作用是尝试获取Code
对象的独占锁。如果它不能(即Code
已经执行)那么什么都不会发生;否则,获取锁,并在执行完成时释放。
答案 1 :(得分:1)
我认为使用Thread
这样效率很低,您应该使用Task
代替。
在C#5中,我会这样做:
private static async Task RunCode(Code code, TimeSpan delay)
{
while (!Stopped)
{
var delayTask = Task.Delay(delay);
Execute(code.CodeLine);
await delayTask;
}
}
然后启动一次(即不在计时器中):
foreach (Code c in listCodes)
{
Task.Run(() => RunCode(c, TimeSpan.FromMilliseconds(1000)));
}
答案 2 :(得分:0)
您需要等待Thread
完成。您可以致电Join
:
List<Thread> threads = new List<Threads>();
foreach(Code c in listCodes)
{
Thread tr = new Thread(delegate() {
Execute(c.CodeLine);
});
threads.Add(tr);
}
foreach(Thread tr in threads)
{
tr.Join();
}
这都在你的外部计时器内。