当执行了下属代码后进度条能够正常运行,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 } );
}
你这多线程等于没有多线程,的确人才!