C# 线程停止运行,可以';我不明白为什么

C# 线程停止运行,可以';我不明白为什么,c#,multithreading,winforms,asynchronous,C#,Multithreading,Winforms,Asynchronous,在一个简单的表单应用程序中,当应用程序启动时,我运行一个恒定的线程。在第一次迭代中,一切都进展顺利,线程方法“thread_ContinousChecker”按预期工作。在它运行一次并且lockChecker.returnBlock()==true命中后,它将不再运行。即,不再尝试。我有一种预感,它与wait lockschecker.checkTime()行有关,但我不明白为什么,如果它工作一次,为什么会停止 注意:只有当Thread_ContinousChecker方法中的第一个if语句命中

在一个简单的表单应用程序中,当应用程序启动时,我运行一个恒定的线程。在第一次迭代中,一切都进展顺利,线程方法“thread_ContinousChecker”按预期工作。在它运行一次并且lockChecker.returnBlock()==true命中后,它将不再运行。即,不再尝试。我有一种预感,它与wait lockschecker.checkTime()行有关,但我不明白为什么,如果它工作一次,为什么会停止

注意:只有当Thread_ContinousChecker方法中的第一个if语句命中时,即如果lockChecker.returnBlock()方法为true,它才会停止工作。如果为假,则继续

这是我的课程

    static class Program
{

    //Instantiate the lockform
    static LockForm lockForm;

    public static bool checkLockForm()
    {
        Form checker = Application.OpenForms["LockForm"];
        return (checker == null);
    }
    public static void toggleLockForm(bool theBool)
    {

        //If theBool (our condition) is true start the form
           if (theBool == true)
           {
               //Checks if form already eixsts
               if (checkLockForm() == true)
               {
                   //Starts the form
                   Application.Run(lockForm = new LockForm());                   
               }
           }
        //Now if theBool is false - we want to close down any instances of the form that we may have started
           if (theBool == false)
           {
               //This is saying if an instance of a LockForm exists
               if (checkLockForm() == false)
               {
                   //Rest of app does not close but that lockform is disabled. 
                   //lockForm.Close();
                   Application.Restart();


               }
           }
    }

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        MyController cont = new MyController();

        //Start new thread for our lock checking 
        Thread thread = new Thread(new ThreadStart(cont.Thread_ContinuousChecker));
        thread.IsBackground = true;
        thread.Name = "Data Polling Thread";
        thread.Start();

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new TrayApp());
    }

    public class MyController
    {

        public Boolean checkForm()
        {
            if (Process.GetProcessesByName("ControlApp.exe").Length > 0)
            {
                // Is running
                return true;
            }
            if (Process.GetProcessesByName("ControlApp.exe").Length == 0)
            {
                // Is not running - so start it
                return false;
            }
            return false;
        }
        public async void Thread_ContinuousChecker()
        {
            while (true)
            {

                if (checkForm() == false)
                {
                    LockLogic lockChecker = new LockLogic();
                    await lockChecker.checkTime();

                    if (lockChecker.returnBlock() == true)
                    {
                        Program.toggleLockForm(true);
                    }
                    if (lockChecker.returnBlock() == false)
                    {
                        Program.toggleLockForm(false);
                    }

                }
                Thread.Sleep(10000);

            }
        }
    }
public async Task checkTime()
    {


        // Read values back from Json file
        var serializedList = await Task.Run(() => File.ReadAllText(_filePathTimes));

        // getting a list of LockTime objects
        var lockTimeList = await Task.Run(() => (List<LockTime>)JsonConvert.DeserializeObject(serializedList, typeof(List<LockTime>), new JsonSerializerSettings { MissingMemberHandling = MissingMemberHandling.Error }));

        //
        if (lockTimeList == null)
        {
            return;
        }
        if(lockTimeList.Count == 0)
        {
            return;
        }

            _lockTimes = lockTimeList;

            //Then I do a foreach loop to go through every value in the start list and add the same located value to my listOfTimes (the list of LockTime objects with start and end)
            for (int x = 0; x < _lockTimes.Count; x++)
            {
                TimeSpan start = new TimeSpan(_lockTimes[x].Start.Hour, _lockTimes[x].Start.Minute, _lockTimes[x].Start.Second);
                TimeSpan end = new TimeSpan(_lockTimes[x].End.Hour, _lockTimes[x].End.Minute, _lockTimes[x].End.Second);
                TimeSpan now = new TimeSpan(DateTime.Now.TimeOfDay.Hours, DateTime.Now.TimeOfDay.Minutes, DateTime.Now.TimeOfDay.Seconds);

                if ((now > start) && (now < end))
                {
                    _block = true;
                }
                else
                {
                    _block = false;
                }
            }


    }
静态类程序
{
//实例化锁窗体
静态锁形锁形;
公共静态bool checkLockForm()
{
表单检查器=Application.OpenForms[“LockForm”];
返回(checker==null);
}
公共静态无效切换锁形式(bool theBool)
{
//如果布尔(我们的条件)为真,则启动表单
if(theBool==true)
{
//检查表单是否已经存在EIXST
如果(checkLockForm()==true)
{
//启动表单
运行(lockForm=new lockForm());
}
}
//现在,如果bool为false,我们希望关闭可能已启动的表单的任何实例
if(theBool==false)
{
//这意味着如果锁窗体的实例存在
if(checkLockForm()==false)
{
//应用程序的其余部分未关闭,但锁定窗体已禁用。
//lockForm.Close();
Application.Restart();
}
}
}
/// 
///应用程序的主要入口点。
/// 
[状态线程]
静态void Main()
{
MyController cont=新的MyController();
//启动新线程进行锁检查
线程线程=新线程(新线程开始(续线程\u ContinuousChecker));
thread.IsBackground=true;
thread.Name=“数据轮询线程”;
thread.Start();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
运行(new TrayApp());
}
公共类MyController
{
公共布尔校验表()
{
if(Process.getProcessByName(“ControlApp.exe”).Length>0)
{
//正在运行
返回true;
}
if(Process.getProcessByName(“ControlApp.exe”).Length==0)
{
//没有运行-所以启动它
返回false;
}
返回false;
}
公共异步无效线程\u ContinuousChecker()
{
while(true)
{
if(checkForm()==false)
{
LockLogic lockChecker=新的LockLogic();
等待lockChecker.checkTime();
if(lockChecker.returnBlock()==true)
{
Program.toggleLockForm(真);
}
if(lockChecker.returnBlock()==false)
{
Program.toggleLockForm(假);
}
}
睡眠(10000);
}
}
}
这是我的LockLogic的.checkTime()方法,我正在上面的程序类中等待它

    static class Program
{

    //Instantiate the lockform
    static LockForm lockForm;

    public static bool checkLockForm()
    {
        Form checker = Application.OpenForms["LockForm"];
        return (checker == null);
    }
    public static void toggleLockForm(bool theBool)
    {

        //If theBool (our condition) is true start the form
           if (theBool == true)
           {
               //Checks if form already eixsts
               if (checkLockForm() == true)
               {
                   //Starts the form
                   Application.Run(lockForm = new LockForm());                   
               }
           }
        //Now if theBool is false - we want to close down any instances of the form that we may have started
           if (theBool == false)
           {
               //This is saying if an instance of a LockForm exists
               if (checkLockForm() == false)
               {
                   //Rest of app does not close but that lockform is disabled. 
                   //lockForm.Close();
                   Application.Restart();


               }
           }
    }

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        MyController cont = new MyController();

        //Start new thread for our lock checking 
        Thread thread = new Thread(new ThreadStart(cont.Thread_ContinuousChecker));
        thread.IsBackground = true;
        thread.Name = "Data Polling Thread";
        thread.Start();

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new TrayApp());
    }

    public class MyController
    {

        public Boolean checkForm()
        {
            if (Process.GetProcessesByName("ControlApp.exe").Length > 0)
            {
                // Is running
                return true;
            }
            if (Process.GetProcessesByName("ControlApp.exe").Length == 0)
            {
                // Is not running - so start it
                return false;
            }
            return false;
        }
        public async void Thread_ContinuousChecker()
        {
            while (true)
            {

                if (checkForm() == false)
                {
                    LockLogic lockChecker = new LockLogic();
                    await lockChecker.checkTime();

                    if (lockChecker.returnBlock() == true)
                    {
                        Program.toggleLockForm(true);
                    }
                    if (lockChecker.returnBlock() == false)
                    {
                        Program.toggleLockForm(false);
                    }

                }
                Thread.Sleep(10000);

            }
        }
    }
public async Task checkTime()
    {


        // Read values back from Json file
        var serializedList = await Task.Run(() => File.ReadAllText(_filePathTimes));

        // getting a list of LockTime objects
        var lockTimeList = await Task.Run(() => (List<LockTime>)JsonConvert.DeserializeObject(serializedList, typeof(List<LockTime>), new JsonSerializerSettings { MissingMemberHandling = MissingMemberHandling.Error }));

        //
        if (lockTimeList == null)
        {
            return;
        }
        if(lockTimeList.Count == 0)
        {
            return;
        }

            _lockTimes = lockTimeList;

            //Then I do a foreach loop to go through every value in the start list and add the same located value to my listOfTimes (the list of LockTime objects with start and end)
            for (int x = 0; x < _lockTimes.Count; x++)
            {
                TimeSpan start = new TimeSpan(_lockTimes[x].Start.Hour, _lockTimes[x].Start.Minute, _lockTimes[x].Start.Second);
                TimeSpan end = new TimeSpan(_lockTimes[x].End.Hour, _lockTimes[x].End.Minute, _lockTimes[x].End.Second);
                TimeSpan now = new TimeSpan(DateTime.Now.TimeOfDay.Hours, DateTime.Now.TimeOfDay.Minutes, DateTime.Now.TimeOfDay.Seconds);

                if ((now > start) && (now < end))
                {
                    _block = true;
                }
                else
                {
                    _block = false;
                }
            }


    }
公共异步任务检查时间()
{
//从Json文件读回值
var serializedList=wait Task.Run(()=>File.ReadAllText(_filePathTimes));
//获取锁定时间对象的列表
var lockTimeList=wait Task.Run(()=>(List)JsonConvert.DeserializeObject(serializedList,typeof(List),new JsonSerializerSettings{MissingMemberHandling=MissingMemberHandling.Error});
//
如果(锁定时间列表==null)
{
返回;
}
if(lockTimeList.Count==0)
{
返回;
}
_锁定时间=锁定时间列表;
//然后我做一个foreach循环,遍历start列表中的每个值,并将相同的定位值添加到我的listOfTimes(带有start和end的LockTime对象列表)
对于(int x=0;x<_lockTimes.Count;x++)
{
TimeSpan start=new TimeSpan(_lockTimes[x].start.Hour、_lockTimes[x].start.Minute、_lockTimes[x].start.Second);
TimeSpan end=new TimeSpan(_lockTimes[x].end.Hour、_lockTimes[x].end.Minute、_lockTimes[x].end.Second);
TimeSpan now=新的时间跨度(DateTime.now.TimeOfDay.Hours,DateTime.now.TimeOfDay.Minutes,DateTime.now.TimeOfDay.Seconds);
如果((现在>开始)和((现在<结束))
{
_block=true;
}
其他的
{
_block=false;
}
}
}

非常感谢能够发现问题所在的任何人。

我有一种预感,问题在于您使用了
Application.Run(lockForm=new lockForm());
。如所示,“此方法向已关闭事件的mainForm参数添加事件处理程序。事件处理程序调用ExitThread来清理应用程序。”

所以,它是按照您所说的做的——将应用程序的生存期绑定到新创建的锁表单的生存期


希望这能有所帮助。

我尝试过通过LockForm foo=new LockForm()等方法启动LockForm,但它无法启动。不断崩溃,所以我不得不去使用应用程序。运行,有什么办法吗?通过“崩溃”我想你的意思是它无法显示窗口,或者它抛出了一个异常,因为你试图从后台启动一个表单