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