110,534
社区成员
发帖
与我相关
我的任务
分享
private delegate void myDelegate1();
private void SetProgressBar1()
{
progressBar1.Value = 0;
Console.Out.WriteLine("thread start");
for (int i = 0; i < 100; i++)
{
System.Threading.Thread.Sleep(500);
progressBar1.Value = i + 1;
}
Console.Out.WriteLine("thread is over");
}
private void TRun1()
{
//判断控件是否在本线程内
if (!this.progressBar1.InvokeRequired)
{
MessageBox.Show("TRun1同一线程内");
Thread.Sleep(2000);
}
else
{
myDelegate1 md1 = new myDelegate1(SetProgressBar1);
MessageBox.Show("TRun1不是同一个线程");
Invoke(md1);
}
}
private void button1_Click(object sender, EventArgs e)
{
// RunWithInvoke();
Thread thread = new Thread(TRun1);
thread.Start();
for (int j = 0; j < 100; j++)
{
System.Threading.Thread.Sleep(500);
Console.Out.WriteLine("j=" + j.ToString());
}
}
private void Form1_Load(object sender, EventArgs e)
{
ThreadPool.QueueUserWorkItem(h =>
{
var rnd = new Random();
for(var i=0; i<100; ++i)
{
Thread.Sleep(rnd.Next(500));
this.progressBar1.BeginInvoke((Action)delegate
{
this.progressBar1.Value = i;
});
}
});
}
当然,你把 BeginInvoke 写成 Invoke 也可以(我是从来不写 Invoke),在此只是一点点体验上的差别(后者变慢)。
private void SetProgressBar1()
{
progressBar1.Value = 0;
Console.Out.WriteLine("thread start");
for (int i = 0; i < 100; i++)
{
System.Threading.Thread.Sleep(500);
progressBar1.Value = i + 1;
}
Console.Out.WriteLine("thread is over");
}
Invoke将这代码放到主线程里面执行,这这段至少50s执行完。
你应该开线程后,在线程里面循环,隔一段时间去修改一次。你不能连续让主线程干那么久
private void button6_Click(object sender, EventArgs e)
{
this.progressBar2.Value = 0;
this.progressBar2.Minimum = 0;
this.progressBar2.Maximum = 100000;//为了看到效果
Thread th = new Thread(ChangeProgressMethod);
th.IsBackground = true;
th.Start(this.progressBar2.Value);
}
private delegate void ChangeProgressDelegate(object data);
private void ChangeProgressMethod(object data)
{
while (true)
{
if (this.progressBar2.Value >= this.progressBar2.Maximum) break;
ChangeProgressDelegate cp = new ChangeProgressDelegate(ChangeProgressMethod);
if (this.progressBar2.InvokeRequired)
{
this.progressBar2.Invoke(cp, data);
Console.Out.WriteLine("Invoke");
}
else
{
Console.Out.WriteLine(this.progressBar2.Value);//这里如果注释掉,UI不会卡住,因为很快执行完成
//会不会是这个console的原因,它使用了另UI的线程,才导致UI界面卡住了,这里要怎样才能找到问题的根源。
//另外如果加上Application.Doevents()就不会卡住了,但貌似跟直接在按钮里面不开新线程运行没什么区别。
data = Convert.ToInt32(data) + 1;
this.progressBar2.Value = Convert.ToInt32(data);
}
}
}