C# 如何检查线程是否完整?

C# 如何检查线程是否完整?,c#,multithreading,C#,Multithreading,我在这方面遇到了很多麻烦。考虑这个例子: public class Test { Thread t; public Test() { t = new Thread(ThreadFunction); } public void Start() { t.Start(); } private void ThreadFunction() { Thread.Sleep(5000); Con

我在这方面遇到了很多麻烦。考虑这个例子:

public class Test {
    Thread t;

    public Test() {
        t = new Thread(ThreadFunction);
    }

    public void Start() {
        t.Start();
    }

    private void ThreadFunction() {
        Thread.Sleep(5000);
        Console.WriteLine("Function Complete");
    }    
}


public static class Main {
    public Main() {
        Test test = new Test();
        test.Start();

        // sleep longer than my worker so it finishes
        Thread.Sleep(10000);

        // a place to place a breakpoint
        bool breakPointHere = true;
    }        
}
现在,我看到了console.log的输出,但当我检查测试的thread对象时,我看到IsAlive仍然为true,ThreadStatus=TheadStatus.Running。为什么会这样?我希望检测线程是否真正完成,但我不清楚如果ThreadFunction()完成,它如何仍被视为正在运行

编辑2:

我终于找到了原因,更新了代码,并将回答我自己的问题

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;


namespace ConsoleApplication1 {
    public abstract class Worker {
        protected bool shutdown;
        protected Thread t;

        private bool _isStopped = true;
        public bool IsStopped {
            get {
                return t.ThreadState == ThreadState.Stopped;
            }
        }

        private bool _isPaused = false;
        public bool IsPaused {
            get {
                return _isPaused;
            }
        }

        private string stringRepresentation;

        public Worker() {
            t = new Thread(ThreadFunction);
            stringRepresentation = "Thread id:" + t.ManagedThreadId;
            t.Name = stringRepresentation;
        }


        public void Start() {
            OnBeforeThreadStart();
            t.Start();
        }

        public void ScheduleStop() {
            shutdown = true;
        }

        public void SchedulePause() {
            OnPauseRequest();
            _isPaused = true;
        }

        public void Unpause() {
            _isPaused = false;
        }

        public void ForceStop() {
            t.Abort();
        }


        /// <summary>
        /// The main thread loop.
        /// </summary>
        private void ThreadFunction() {
            OnThreadStart();
            while (!shutdown) {
                if (!IsPaused) {
                    if (!OnLoop()) {
                        break;
                    }
                }
                Thread.Sleep(1000);
            }
            OnShutdown();
        }

        public abstract void OnBeforeThreadStart();
        public abstract void OnThreadStart();
        public abstract bool OnLoop();
        public abstract void OnShutdown();
        public abstract void OnPauseRequest();


        public override string ToString() {
            return stringRepresentation;
        }
    }


    public class Test : Worker {
        public override void OnBeforeThreadStart() {
            Log.WriteLine(this + ": Thread about to be started...");
        }

        public override void OnThreadStart() {
            Log.WriteLine(this + ": Thread Started!");
        }

        public override bool OnLoop() {
            Log.WriteLine(this + ": I am doing the things...");
            return true;
        }

        public override void OnShutdown() {
            Log.WriteLine(this + ": Shutting down!");
        }

        public override void OnPauseRequest() {            
        }
    }



public static class Log {
    public delegate void LogDelegate(string text, string eventTime, Severity severity);

    public static event LogDelegate OnWriteLine;

    private static Queue<string> _pendingFileWrites = new Queue<string>();


    public enum Severity {
        Info,
        Warning,
        Error
    }


    public static void WriteLine(object line, Severity severity = Severity.Info) {
        string eventTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
        string formatted = "[" + eventTime + "]: " + line;
        Console.WriteLine(formatted);

        lock (_pendingFileWrites) {
            _pendingFileWrites.Enqueue(formatted);
        }

        if (OnWriteLine != null) {
            // this is the offending line:
            OnWriteLine.Invoke((string)line, eventTime, severity);
        }
    }


    public static void WriteToFile(string path) {
        lock(_pendingFileWrites) {
            StreamWriter sw = File.AppendText(path);        
            while(_pendingFileWrites.Count > 0) {
                sw.WriteLine(
                    _pendingFileWrites.Dequeue()
                );
            }
            sw.Close();
        }   
    }
}



    class Program {
        static void Main(string[] args) {
            List<Test> tests = new List<Test>();
            for(int i = 0; i < 10; i++) {
                Test test = new Test();
                test.Start();
                tests.Add(test);
            }

            // sleep a little bit so they do the things
            Thread.Sleep(10000);

            foreach (Test test in tests) {
                test.ScheduleStop();
            }

            bool allStopped;
            do {
                allStopped = true;
                foreach (Test test in tests) {
                    if (!test.IsStopped) {
                        allStopped = false;
                        break;
                    }
                }
            } while (!allStopped);

            Console.WriteLine("Done!");

            // a place to place a breakpoint
            bool breakPointHere = true;
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用系统线程;
使用System.Threading.Tasks;
命名空间控制台应用程序1{
公共抽象类工作者{
保护性停机;
保护螺纹t;
private bool_isStopped=true;
公共图书馆{
得到{
返回t.ThreadState==ThreadState.Stopped;
}
}
私有bool_isPaused=false;
公共场所{
得到{
返回(i);;
}
}
私有字符串表示;
公职人员(){
t=新螺纹(螺纹功能);
stringRepresentation=“线程id:+t.ManagedThreadId;
t、 名称=字符串表示;
}
公开作废开始(){
OnBeforeThreadStart();
t、 Start();
}
public void ScheduleStop(){
关机=真;
}
公共无效计划暂停(){
OnPauseRequest();
_isPaused=真;
}
公共无效取消暂停(){
_isPaused=false;
}
公共停车场{
t、 中止();
}
/// 
///主线程循环。
/// 
私有函数(){
OnThreadStart();
而(!关机){
如果(!i暂停){
如果(!OnLoop()){
打破
}
}
睡眠(1000);
}
OnShutdown();
}
公共摘要void OnBeforeThreadStart();
公共摘要在readstart()上无效;
公共抽象bool OnLoop();
公共摘要void OnShutdown();
公共摘要void OnPauseRequest();
公共重写字符串ToString(){
返回表示;
}
}
公开班级考试:工人{
public override void OnBeforeThreadStart(){
WriteLine(此+“:即将启动的线程…”);
}
public override void OnThreadStart(){
Log.WriteLine(此+“:线程已启动!”);
}
公共覆盖bool OnLoop(){
Log.WriteLine(这个+“:我正在做这些事情…”);
返回true;
}
公共覆盖无效OnShutdown(){
Log.WriteLine(此+“:正在关闭!”);
}
公共覆盖无效OnPauseRequest(){
}
}
公共静态类日志{
公共委托void LogDelegate(字符串文本、字符串事件时间、严重性);
公共静态事件日志委托OnWriteLine;
私有静态队列_pendingFileWrites=新队列();
公共枚举严重性{
信息,
警告
错误
}
公共静态无效写入线(对象行,严重性=严重性.Info){
字符串eventTime=DateTime.Now.ToString(“yyyy-MM-dd HH:MM:ss”);
字符串格式为=“[”+事件时间+”]:“+行;
Console.WriteLine(格式化);
锁定(_pendingFileWrites){
_pendingFileWrites.Enqueue(格式化);
}
if(OnWriteLine!=null){
//这是一条令人不快的线:
调用((字符串)行、事件时间、严重性);
}
}
公共静态void WriteToFile(字符串路径){
锁定(_pendingFileWrites){
StreamWriter sw=File.AppendText(路径);
而(_pendingFileWrites.Count>0){
sw.WriteLine(
_pendingFileWrites.Dequeue()
);
}
sw.Close();
}   
}
}
班级计划{
静态void Main(字符串[]参数){
列表测试=新列表();
对于(int i=0;i<10;i++){
测试=新测试();
test.Start();
测试。添加(测试);
}
//睡一点,这样他们就能做事情了
睡眠(10000);
foreach(测试中的测试){
test.ScheduleStop();
}
布尔停了下来;
做{
allStopped=true;
foreach(测试中的测试){
如果(!test.IsStopped){
allStopped=false;
打破
}
}
}而(!全部停止);
控制台。WriteLine(“完成!”);
//放置断点的位置
bool=true;
}
}
}

您真的需要睡眠来等待线程完成吗? 如果您不这样做,一个更好、更健壮的解决方案将是使用


你真的需要睡觉来等待线程完成吗? 如果您不这样做,一个更好、更健壮的解决方案将是使用


我认为你最初的测试让你相信
.IsAlive
是真的,但它有一些缺陷,我在你的问题中对你的程序进行了如下调整,使它能够编译并能够看到它创建了哪个线程

public class Program
{
    public class Test
    {
        Thread t;

        public Test()
        {
            t = new Thread(ThreadFunction);
            t.Name = "TestThread";
        }

        public void Start()
        {
            t.Start();
        }

        private void ThreadFunction()
        {
            Thread.Sleep(5000);
            Console.WriteLine("Function Complete");
        }
    }


    public static void Main()
    {
        Test test = new Test();
        test.Start();

        // sleep longer than my worker so it finishes
        Thread.Sleep(10000);

        // a place to place a breakpoint
        bool breakPointHere = true;
    }
}
下面是从ThreadFunction内部运行线程的屏幕截图

这是节目结尾的截图

请注意,没有“TestThread”线程

这是本地人窗口的屏幕截图

IsAlivepublic class Program
{
    public class Test
    {
        Thread t;

        public Test()
        {
            t = new Thread(ThreadFunction);
            t.Name = "TestThread";
        }

        public void Start()
        {
            t.Start();
        }

        private void ThreadFunction()
        {
            Thread.Sleep(5000);
            Console.WriteLine("Function Complete");
        }
    }


    public static void Main()
    {
        Test test = new Test();
        test.Start();

        // sleep longer than my worker so it finishes
        Thread.Sleep(10000);

        // a place to place a breakpoint
        bool breakPointHere = true;
    }
}
private void LogToForm(object line, string eventTime, Log.Severity severity) {
            if (dataGridView_LogInfo.InvokeRequired) {
                dataGridView_LogInfo.Invoke (
                    new Action<object, string, Log.Severity>(LogtoFormCallback), 
                    new object[] { line, eventTime, severity }
                );

            } else {
                LogtoFormCallback(line, eventTime, severity);
            }
        }