2011-09-18 95 views
0

这个程序在线程中写入从1到5000的数字,但主窗体仍然冻结。 错误在哪里?提前致谢。为什么表单冻结?

代码:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using System.Net; 
using System.IO; 
using System.Threading; 

namespace WindowsFormsApplication1 
{ 
    public partial class Form1 : Form 
    { 
     int how, current; 
     bool job; 
     Object lockobj = new Object(); 

     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      MessageBox.Show("Started!"); 
      how = 5000; 
      current = 0; 
      job = true; 
      Thread worker = new Thread(Go); 
      worker.Name = "1"; 
      worker.Start(); 
     } 

     private void Go() 
     { 
      while (job) 
      { 
       if (current < how) 
       { 

        lock (lockobj) 
        { 
         current++; 
        } 

        log(string.Format("Thread #{0}: {1}", Thread.CurrentThread.Name, current)); 
       } 
       else 
       { 
        job = false; 
       } 
      } 
     } 


     private void log(string text) 
     { 
      Action A = new Action(() => 
      { 
       richTextBox1.AppendText(text + System.Environment.NewLine); 
      }); 

      if (richTextBox1.InvokeRequired) 
       this.BeginInvoke(A); 
      else A(); 
     } 
    } 


} 

回答

3

因为大部分工作将在

 if (richTextBox1.InvokeRequired) 
      this.BeginInvoke(A); 

中度过,虽然你调用的形式,它已被锁定。

做一些真正的工作,如Thread.Sleep(1000); :-),而不是current++;,你的表单将会在更新之间进行响应。

3

冻结,因为你是在文本框非常快渲染和图形用户界面没有时间保持同步。请记住,此渲染发生在主GUI线程上,并且通过调用BeginInvoke来更快速地更新文本框实际上会占用此主GUI线程的所有资源。尝试降低您在日志记录的频率以避免此行为。