C# 使用IsAlive检查线程是否完成失败

C# 使用IsAlive检查线程是否完成失败,c#,multithreading,C#,Multithreading,在C项目中,我有一个ThreadSpawner类,它生成线程并在运行作业的列表中跟踪它们。如果线程完成,则应从该列表中删除它们 到目前为止,我用Thread.IsAlive属性尝试了它,但它不起作用,因为它似乎总是正确的,而且永远不会变为错误 我想在IsFinished方法中检查的是,线程是否已经死了,并且不再运行,我假设当DoJob方法离开时,会自动发生这种情况 有没有关于如何检查它们的提示 我不知道哪个线程状态表示线程不再存在 我的示例代码: public class ThreadSpa

在C项目中,我有一个ThreadSpawner类,它生成线程并在运行作业的列表中跟踪它们。如果线程完成,则应从该列表中删除它们

到目前为止,我用Thread.IsAlive属性尝试了它,但它不起作用,因为它似乎总是正确的,而且永远不会变为错误

我想在IsFinished方法中检查的是,线程是否已经死了,并且不再运行,我假设当DoJob方法离开时,会自动发生这种情况

有没有关于如何检查它们的提示

我不知道哪个线程状态表示线程不再存在

我的示例代码:

  public class ThreadSpawner {

  private List<SpawnedThread> _runningJobs;
  private bool _isStopRequested;
  private int maxRunningJobs = 3;
  private Thread _thread; 
  
  public ThreadSpawner() {
    _runningJobs = new List<SpawnedThread>();
    _isStopRequested = false;
    _thread = null;
  }
  
  public void Start() {
    _thread = new Thread(DoJob);
    _thread.Start();
  }
  
  public void DoJob() {
    while(!_isStopRequested) {

      //check if there are finished jobs in the list and remove them if they are finished
      for (int i = _runningJobs.Count-1; i >= 0; i--) {
        if (_runningJobs.ElementAt(i).IsFinished()) {
            _runningJobs.RemoveAt(i);
        }
      }

      //spawn threads if possible and required
      if (_runningJobs.Count less maxRunningJobs && ShouldThreadBeSpawned()) {
        SpawnedThread st = new SpawnedThread();
        _runningJobs.Add(st);
        st.Start();
      }

      Thread.Sleep(100);
    }
  }
  
  public void Stop() {
    _isStopRequested = true;

    for (int i = 0; i less _runningJobs.Count; i++) {
      _runningJobs.ElementAt(i).Stop();
    }
  }

  public bool IsFinished() {
    return _thread == null || ( _runningJobs.Count == 0 && _thread.IsAlive);
  }
  
  private bool ShouldThreadBeSpawned() {
    return true; //actually whatever the criteria says
  }
}

public class SpawnedThread {

  private bool _isStopRequested;
  private Thread _thread; 
  
  public ThreadSpawner() {
    _isStopRequested = false;
    _thread = null;
  }
  
  public void Start() {
    _thread = new Thread(DoJob);
    _thread.Start();
  }
  
  public void DoJob() {
    // does whatever it should do
    // and leaves the DoJob method
    // and I assumed when this method is left IsAlive would become false but it doesn't
  }
  
  public void Stop() {
    _isStopRequested = true;
  }

  public bool IsFinished() {
    return _thread == null || _thread.IsAlive;
  }
  
}
精炼问题 我如何启动线程/任务,以便跟踪正在运行的线程/任务,并能够通过代码停止它们,并且能够为每个线程/任务调用一些代码来停止包含的进程

更多细节 整个系统用于.NET核心windows服务,请参见我的其他问题。windows服务启动ThreadSpawner。ThreadSpawner查询数据库中要执行的作业。对于每个作业,它都会生成一个SpankedThread。这个线程从数据库中查询另一组数据,通过网络获取一些文件。然后,SpawnedThread一个接一个地启动一些调用可执行文件的进程,并将结果从一个可执行文件传递到下一个可执行文件调用。然后将生成的文件放回并将结果存储在数据库中

一切都正常,除了一个问题,我不知道当windows服务停止时如何判断线程是否正在运行,以及如何以一种同时停止进程的方式杀死生成的线程。同样的机制也用于检查被调用的exe是否挂起,并使用其进程和SpawnedThread杀死挂起的exe

为什么我没有使用ThreadPool和ThreadPool.QueueUserWorkItem 首先我有。但我无法跟踪哪些线程正在运行,也无法以停止进程的方式杀死它们。无论是在windows服务停止的情况下,还是在检测到外部exe挂起的情况下

为什么我没有使用任务
从来没有和他们合作过,我们团队决定采用线程。我很高兴看到关于如何处理任务的建议。

我认为需要改变

 public bool IsFinished() {
    return _thread == null || _thread.IsAlive;
  }


使用线程而不是任务有什么特殊原因吗?因为线程是一种不好的实践,任务更容易检查……这听起来像是使用任务和/或TPL进行完全重写的一个很好的候选,TPL内置了对取消和状态的支持。首先,保持像isStopRequested这样的布尔值需要学习记忆障碍,以理解为什么简单的赋值不起作用。这并不有趣。你也可以使用一个回调函数,比如说ThreadCompleted,并在线程结束时调用这个函数。在这个函数中,您可以编写代码从正在运行的作业列表中删除。@您的意思是,与任务一样,MIDree具有手动回调和创建新线程的开销time@monty即使您不想出于任何原因使用任务,也不应该使用原始线程。创建线程会带来开销。所有Windows应用程序都可以利用预分配的、可重用的线程池。用于在线程池线程上执行函数。这就是defaultYou执行任务的方式你真是太天才了。在所有那些复杂的构造中,我忽略了那个小细节。这是非常正确的。如果可以的话,我会请你喝一杯。亲切的问候、衷心的感谢和我所有的爱:-
 public bool IsFinished() {
    return _thread == null || !_thread.IsAlive;
  }