应用程序没有响应

时间:2016-03-13 17:04:14

标签: c# .net winforms

应用程序应该做什么

此应用程序应该输入时间(秒,分钟和小时)并在此之后关闭计算机。它还应该在文本框中更新计算机关闭之前的剩余时间。

应用程序实际执行的操作

我遇到了一个“修复”的问题,即跨越线程的被叫ac不安全,所以我修复了它,现在我没有得到那个错误。但是,updateThread不会更新并打印剩余的时间;并且文本框没有附加“test”。 UI也变为无响应。任何帮助将不胜感激。

另外,如果您发现其他任何可以做得更好的事情,请发表评论并解释。谢谢!

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ShutdownPC
{
    public partial class Form1 : Form
    {
        int inputHours;
        int inputMinutes;
        int inputSeconds;

        Thread sleepingThread;
        Thread updatingThread;

        NotifyIcon shutdownPCIcon;
        Icon defaultIcon;

        public Form1()
        {
            InitializeComponent();
            defaultIcon = new Icon("defaultIcon.ico");
            shutdownPCIcon = new NotifyIcon();
            shutdownPCIcon.Icon = defaultIcon;
            shutdownPCIcon.Visible = true;

            MenuItem progNameMenuItem = new MenuItem("ShutdownPC by Conor");
            MenuItem breakMenuItem = new MenuItem("-");
            MenuItem quitMenuItem = new MenuItem("Quit");
            ContextMenu contextMenu = new ContextMenu();
            contextMenu.MenuItems.Add(progNameMenuItem);
            contextMenu.MenuItems.Add(breakMenuItem);
            contextMenu.MenuItems.Add(quitMenuItem);
            shutdownPCIcon.ContextMenu = contextMenu;

            shutdownPCIcon.Text = "ShutdownPC";

            quitMenuItem.Click += QuitMenuItem_Click;
        }

        private void QuitMenuItem_Click(object sender, EventArgs e)
        {
            shutdownPCIcon.Dispose();
            sleepingThread.Abort();
            updatingThread.Abort();
            this.Close();
        }

        public void sleepThread()
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new MethodInvoker(sleepThread));
            }
            else {
                textBox1.Enabled = false;
                textBox2.Enabled = false;
                textBox3.Enabled = false;
                button1.Enabled = false;

                int totalMilliseconds = ((inputHours * 3600) + (inputMinutes * 60) + inputSeconds) * 1000;
                Thread.Sleep(totalMilliseconds);
                //Process.Start("shutdown", "/s /t 0");
                richTextBox1.AppendText(String.Format("test"));
            }
        }

        public void updateThread()
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new MethodInvoker(updateThread));
            }
            else {
                int totalSeconds = (inputHours * 3600) + (inputMinutes * 60) + inputSeconds;
                while (totalSeconds > 0)
                {
                    TimeSpan time = TimeSpan.FromSeconds(totalSeconds);

                    string timeOutput = time.ToString(@"hh\:mm\:ss");

                    richTextBox1.AppendText(String.Format(timeOutput));
                    Thread.Sleep(1000);
                    richTextBox1.Clear();
                    totalSeconds--;
                }
            }
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            inputHours = Convert.ToInt32(textBox1.Text);
            inputHours = int.Parse(textBox1.Text);
        }

        private void textBox2_TextChanged(object sender, EventArgs e)
        {
            inputMinutes = Convert.ToInt32(textBox2.Text);
            inputMinutes = int.Parse(textBox2.Text);
        }

        private void textBox3_TextChanged(object sender, EventArgs e)
        {
            inputSeconds = Convert.ToInt32(textBox3.Text);
            inputSeconds = int.Parse(textBox3.Text);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            updatingThread = new Thread(new ThreadStart(updateThread));
            updatingThread.Start();
            sleepingThread = new Thread(new ThreadStart(sleepThread));
            sleepingThread.Start();
        }

        private void richTextBox1_TextChanged(object sender, EventArgs e)
        {
        }
    }
}

1 个答案:

答案 0 :(得分:2)

在单独的线程中运行的方法的开头使用Invoke是个坏主意,因为所有代码都在GUI线程中运行并锁定它。

您应该只调用GUI更新代码!!!