如何使线程以正确的顺序运行

本文关键字:顺序 运行 何使 线程 | 更新日期: 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.PulseMonitor.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());
    }
}