【问题标题】:Thread stops running, can't figure out why线程停止运行,无法弄清楚为什么
【发布时间】:2014-05-21 02:30:30
【问题描述】:

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

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

这是我的程序类

    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);

            }
        }
    }

这是我在上面的 Program 类中等待的 LockLogic 的 .checkTime() 方法

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;
                }
            }


    }

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

【问题讨论】:

    标签: c# multithreading winforms asynchronous


    【解决方案1】:

    我有一种预感,问题在于您对Application.Run(lockForm = new LockForm()); 的使用。根据http://msdn.microsoft.com/en-us/library/ms157902(v=vs.110).aspx,“此方法将事件处理程序添加到 Closed 事件的 mainForm 参数。事件处理程序调用 ExitThread 来清理应用程序。”

    所以,它正在做你告诉它的事情 - 将应用程序的生命周期绑定到新创建的 LockForm 的生命周期。

    希望这会有所帮助。

    【讨论】:

    • 我尝试通过 LockForm foo = new LockForm() 等方法启动 LockForm,但它就是无法启动。一直在崩溃,所以这就是为什么我不得不去使用 Application.Run,​​有什么办法解决这个问题吗?
    • 通过“崩溃”,我假设您的意思是它未能显示窗口,或者由于您试图从后台线程启动表单而引发异常。我猜你必须想办法运行从 UI 线程 (stackoverflow.com/questions/2367718/…) 创建表单的代码。
    • 我确实读过它,但我只是不明白发生了什么。也许我应该在一天左右的时间里回来。重新开始。更烦人的是,一旦我手动关闭表单,线程就会继续。
    猜你喜欢
    • 1970-01-01
    • 2014-12-08
    • 1970-01-01
    • 1970-01-01
    • 2013-12-07
    • 2014-07-22
    • 2015-04-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多