2016-03-13 74 views
-2

我只想说,这是我的第一个Windows窗体应用程序使裸陪我:)应用程序没有响应

哪些应用应该做

此应用程序应该采取的时间输入(秒,分钟和小时),然后关闭计算机。它还应该更新文本框,并保留多长时间直到计算机关闭。

什么应用程序实际上不会

我有一个问题,我“固定”,其中跨线程调用的交流并不安全,所以我固定它,我现在不得到这个错误。但是,updateThread不更新并打印剩下的时间;并且文本框没有得到“测试”附加到它。用户界面也变成不响应。任何帮助将非常感激。

此外,如果您发现其他方面可以做得更好,请评论并解释。谢谢!

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) 
     { 
     } 
    } 
} 
+2

您不必为这样的操作创建新的线程,给System.Timers.Timer或System.Windows.Forms.Timer一个镜头! – John

+1

或等待Task.Delay - 但约翰是对的;这是一个计时器的目的。这个简短的程序充满了不好的做法;不要使用这样的线程。没有必要使用任何额外的线程来完成这样简单的任务。 –

+0

同意约翰。这是最简单的方法。但在理解线程编程的情况下,您应该查看我的答案。 –

回答

2

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

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

+0

工作过,谢谢。 – Conor