java doevents_Application.DoEvents()和多线程

本文探讨了在Java应用中如何处理UI假死问题,通过对比Application.DoEvents()方法和多线程两种方式。示例代码展示了如何使用多线程更新UI,避免窗体假死,并讨论了多线程的正确实现方式,以减少潜在错误和提高性能。
摘要由CSDN通过智能技术生成

如何使用Application.DoEvents() 和 多线程?

首先将以下代码放到Button事件里面:

private void btnStart_Click(object sender, EventArgs e)

{

for (int q = 0; q < 100000; q++)

{

textBox1.Text = q.ToString();

}

}

你会发现当点击Start按钮后,循环会一直进行,此时窗体会出现假死的状态,如:无法拖动。直到循环结束,textBox1中才会显示出结果。如何解决窗体的假死状态??

修改以上代码如下:

private void btnStart_Click(object sender, EventArgs e)

{

for (int q = 0; q < 100000; q++)

{

textBox1.Text = q.ToString();

//实时响应文本框中的值

Application.DoEvents();

}

}

此时再次点击Start按钮后,textBox中的数字会不断改变,同时,你也可以拖动窗体。。。

3125829.html

但是这样使用Application.DoEvents()好吗?如果用多线程来实现相同的效果呢?

多线程实现代码如下:

public Form1()

{

InitializeComponent();

//不捕获跨线程调用引起的异常

CheckForIllegalCrossThreadCalls = false;

}

private void btnStart_Click(object sender, EventArgs e)

{

Thread s1 = new Thread(new ThreadStart(ThreadMeth));

s1.Start();

}

public void ThreadMeth()

{

for (int q = 0; q < 100000; q++)

{

textBox1.Text = q.ToString();

}

}

注意:Form1()里面添加了一行代码,解决跨线程调用产生的异常。

以上代码和使用Application.DoEvents()达到相同的效果。

下面我们来比较一下,使用Application.DoEvents()和使用多线程哪个更耗时?

代码如下:

public void ThreadMeth()

{

label1.Text = DateTime.Now.ToString();

for (int q = 0; q < 100000; q++)

{

textBox1.Text = q.ToString();

}

label5.Text = DateTime.Now.ToString();

}

private void btnStartDo_Click(object sender, EventArgs e)

{

label3.Text = DateTime.Now.ToString();

for (int q = 0; q < 100000; q++)

{

textBox2.Text = q.ToString();

Application.DoEvents();//实时响应文本框中的值

}

label6.Text = DateTime.Now.ToString();

}

3125829.html

(假设以上比较时间的代码处在正确的位置)由此可知,Application.DoEvents()消耗的时间更少,但这里并不建议使用Application.DoEvents(),因为它会引起很多未知的错误。

补充:由于显示的定义 CheckForIllegalCrossThreadCalls = false;并不是好的方法,下面来改进一下,如下:

int i;

private void btnStart_Click(object sender, EventArgs e)

{

Thread s1 = new Thread(new ThreadStart(ThreadMeth));

s1.Start();

}

private void ThreadMeth()

{

for ( i = 0; i < 100000; i++)

{

MethodInvoker mi = new MethodInvoker(Count);

this.Invoke(mi);

//BeginInvoke(mi);

}

}

private void Count()

{

textBox1.Text = i.ToString();

}

MethodInvoker实质上是一个委托,查看其定义可知...

using System;

namespace System.Windows.Forms

{

// 摘要:

// 表示一个委托,该委托可执行托管代码中声明为 void 且不接受任何参数的任何方法。

public delegate void MethodInvoker();

}

以上用匿名委托的方式似乎更简洁,代码如下:

private void btnStart_Click(object sender, EventArgs e)

{

new Thread((ThreadStart)(delegate()

{

for (int i = 0; i < 10000; i++)

{

label1.Invoke((MethodInvoker)delegate()

{

textBox1.Text = i.ToString();

});

};

}))

.Start();

}

在次线程上计算,在主线程上调用label。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值