问题描述
- c#多线程2个托管只跑了一个
-
当执行了下属代码后进度条能够正常运行,label1.text并没有根据x值的变化连续变化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.Threading; namespace WindowsFormsApplication6 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } DateTime dt; int x = 0; int y = 0; private void button1_Click(object sender, EventArgs e) { timer1.Enabled = true; x = 0; Thread myThread = new Thread(DoData); Thread myThread1 = new Thread(Viewlabel); myThread.IsBackground = true; myThread1.IsBackground = true; myThread1.Start(int.Parse(textBox1.Text)); myThread.Start(int.Parse(textBox1.Text)); dt = DateTime.Now; } private delegate void ViewlabelDelegate(object number); private void Viewlabel(object number) { int i = 1, sum = 0; if (label1.InvokeRequired) { ViewlabelDelegate v = Viewlabel; label1.Invoke(v, number); } else { bool flag = true; while (flag) { flag = y < (int)number; sum += i++; label1.Text = sum.ToString(); Application.DoEvents(); } MessageBox.Show(sum.ToString()); } } private delegate void DoDataDelegate(object number); /// <summary> /// 进行循环 /// </summary> /// <param name="number"></param> private void DoData(object number) { if (progressBar1.InvokeRequired) { DoDataDelegate d = DoData; progressBar1.Invoke(d, number); } else { progressBar1.Maximum = (int)number; bool flag = true; while (flag) { flag = x < (int)number; progressBar1.Value = x; Application.DoEvents(); } MessageBox.Show(DateTime.Now.Subtract(dt).ToString()); //循环结束截止时间 } } private void timer1_Tick(object sender, EventArgs e) { x = x + 1; y = y + 1; } } }
当把Viewlabel代码改为下面代码后sum正常计数
private void Viewlabel(object number) { int i = 1, sum = 0; while (x < (int)number) { sum += i++; Application.DoEvents(); } MessageBox.Show(sum.ToString());
解决方案
if (xxxx.InvokeRequired)是判断是否跨线程,
else后面是调用控件所在线程,也就是主线程来执行的,你将子线程的任务放到主线程上执行了。
所以你才会用到 Application.DoEvents()
解决方案二:
无论你是否多线程,关键在于
Application.DoEvents();
当你修改label的 text,winforms本身不会去修改显示的文字,而是丢一条重绘文本的消息给操作系统,操作系统负责在界面上绘制新的文本。
Application.DoEvents();使得UI线程会处理挂起的消息,其中包含了更新label显示的消息,这样界面才能更新。如果这样的代码得不到执行,当然界面不更新了。
解决方案三:
人才啊,这种跨线程调用控件应该是自创的,完全看不懂。
跨线程调用进度条:
private delegate void DoDataDelegate(int iVal);
private void progressBarVal(int iVal)
{
progressBar1.Value = iVal;
}
工作线程:
{
DoDataDelegate del = new DoDataDelegate(progressBarVal);
progressBar1.invoke(del,new object[] { 50 } );
}
解决方案四:
你这多线程等于没有多线程,的确人才!
时间: 2024-09-19 19:37:37