如何使线程以正确的顺序运行
本文关键字:顺序 运行 何使 线程 | 更新日期: 2023-09-27 18:34:25
有两个流,第一个流显示进程表,而第二个流认为它们计数并显示。最初为第一个启动,然后是第二个:
Thread t1 = new Thread(tmh1.FillTable);
Thread t2 = new Thread(tmh1.GetGeneralInfo);
t1.Start();
t2.Start();
以下是在线程中运行的方法:
public void FillTable()
{
while (true)
{
lock (lockObj)
{
arr.Clear();
arr.AddRange(Process.GetProcesses());
TableFormatter.Line();
TableFormatter.Row("Name", "ID", "threads quantity", "Start time");
TableFormatter.Line();
}
Thread.Sleep(interval);
}
}
public void GetGeneralInfo()
{
while (true)
{
lock (lockObj)
{
Console.WriteLine(arr.Count.ToString());
}
Thread.Sleep(interval);
}
}
结果是:
0
-----------------------------------------------------------------------------
| Name | ID | threads quantity| Start time |
-----------------------------------------------------------------------------
但应如下:
-----------------------------------------------------------------------------
| Name | ID | threads quantity| Start time |
-----------------------------------------------------------------------------
**68**
如何使胎面以正确的顺序运行?
线程
应该并行运行。如果您希望在第一个线程完成时执行第二个线程执行的任务,只需让第一个线程也执行第二个任务即可。
您还可以使用任务并行库的方法一个接一个地运行任务。
Task.Factory.StartNew(() => tmh1.FillTable()).ContinueWith(() => tmh1.GetGeneralInfo(), TaskScheduler.FromCurrentSynchronizationContext());
我会使用Task。 例如:
Task.Factory.StartNew(tmh1.FillTable).ContinueWith(tmh1.GetGeneralInfo)
虽然,目前还不清楚为什么你想要两个线程。 以下方法也应该有效:
Thread t1 = new Thread(()=>{tmh1.FillTable; tmh1.GetGeneralInfo();});
t1.Start();
这段代码非常奇怪,很难确定为什么要创建 2 个相互追逐运行的线程。
假设所需的效果是在不同的线程上在不同时间运行两个事情,则最简单的方法是利用任务并行库(假设可以使用 C# 4)。其示例如下:
Task.Factory
.StartNew(() => Console.WriteLine("This is the first"))
.ContinueWith(t => Console.WriteLine("This is the second"));
Console.ReadLine();
如果要手动创建线程,则应阅读信令构造
可以使用重置事件来使用信令(请参阅 C# 中的自动重置事件或手动重置事件)。但是在锁中调用等待信号可能很危险(例如死锁)
只做你发布的代码 我不得不说,在这里使用线程毫无意义。我猜它比你提出的要多。也许你删减了代码以制作一个更小的帖子?
无论如何,需要最少调整和重构的解决方案是使用 Monitor.Pulse
和 Monitor.Wait
。
public void FillTable()
{
while (true)
{
Thread.Sleep(interval);
lock (lockObj)
{
arr.Clear();
arr.AddRange(Process.GetProcesses());
TableFormatter.Line();
TableFormatter.Row("Name", "ID", "threads quantity", "Start time");
TableFormatter.Line();
Monitor.Pulse(lockObj);
}
}
}
public void GetGeneralInfo()
{
while (true)
{
lock (lockObj)
{
Monitor.Wait(lockObj);
Console.WriteLine(arr.Count.ToString());
}
}
}
不过,还有其他技术可以使用。一种常见的方法是使用生产者-消费者模式。这对于BlockingCollection
类来说很容易。
private BlockingCollection<Process[]> queue = new BlockingCollection<Process[]>();
public void FillTable()
{
while (true)
{
Thread.Sleep(interval);
queue.Add(Process.GetProcesses());
}
}
public void GetGeneralInfo()
{
while (true)
{
Process[] processes = queue.Take();
Console.WriteLine(processes.Length.ToString());
}
}