C# Windows Form,点某个按钮后,长时间运行时,如果实时显示窗口内容。 RT,有没有简单的办法? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 C# Windows Form,点某个按钮后,长时间运行时,如何实时显示窗口内容。 1、Application.DoEvents();2、异步 //举个例子: private void button1_Click(object sender, System.EventArgs e) { ExcuteCalDelegate c=new ExcuteCalDelegate(Cal); c.BeginInvoke(null,null); } private delegate void ExcuteCalDelegate(); private void Cal() { for(int i=1;i<=10000000;i++) { this.textBox1.Text+=(i*i).ToString()+"\r\n"; //Application.DoEvents(); } } 使用异步委托。但是3楼的方法,在后台线程调用了UI线程的控件,这样非常危险,非常容易出现异常。在后台线程中对控件的操作,要把操作方法使用代理和空间的Invoke方法封送到后台线程,才能确保线程安全。 public partial class FormTest : Form { private delegate void InvokeDelegate(); private delegate void SetTextBoxHandler(TextBox tb,string str); private InvokeDelegate invokeDelegate; private SetTextBoxHandler deleChangeText; public FormTest() { InitializeComponent(); } private void FormTest_Load(object sender, EventArgs e) { //初始化两个代理实例 this.invokeDelegate = new InvokeDelegate(this.FunTest); this.deleChangeText = new SetTextBoxHandler(this.SetTextBoxValue); } private void FunTest() { for (int i = 0; i < 100000; i++) { //搜索控件句柄,判断控件是否生成,不生成则返回false,此时就不能调用begininvoke方法了 //另外,如果对if内部语句的调用发生在同一线程(即UI线程或主线程),则InvokeRequired将返回false; if (this.textBox1.InvokeRequired) { this.BeginInvoke(this.deleChangeText, new object[] { this.textBox1, i.ToString() }); //一定注意,Sleep的动作一定不能放在SetTextBoxValue()方法中,因为控件的BeginInvoke()会将SetTextBoxValue()方法 //封送至后台线程,这就变成了在后台线程中让主线程Sleep300ms的时间,而不是让后台线程Sleep300ms了。 Thread.Sleep(300); } else { this.SetTextBoxValue(this.textBox1, i.ToString()); Thread.Sleep(300); } } } private void SetTextBoxValue(TextBox tb, string str) { tb.Text = str; tb.Refresh(); //下面的句子表明,即使该方法被封送到后台线程后,该方法内的线程是主线程,而非后台线程 //MessageBox.Show(Thread.CurrentThread.IsBackground.ToString()); } //在后台线程中调用FunTest() private void button1_Click(object sender, EventArgs e) { //使用异步调用,开辟后台线程 this.invokeDelegate.BeginInvoke(null, null); } 使用DoEvent容易破坏类的结构 处理数据量不大要求不高的话可以用time 控件哦,比线程简单多了 CRUD的R到底是Retrieve还是Read? C# 文件写入问题 什么方法可以把类对象序列化成一个字符串 castle问题 如何通过变量传入事件处理方法 [求教]web程序生成Excel文件的问题 winform有没有实现象.net IDE那样的界面的摸板? 怎样改变父窗体控件的属性值? 请问怎么从备份文件生成DataSet或者直接导入数据库? 多线程访问数据库问题 怎样将长文件名转成短文件名 请教在aspx页面中插入C#代码给控件的Text赋值?
2、异步
private void button1_Click(object sender, System.EventArgs e)
{
ExcuteCalDelegate c=new ExcuteCalDelegate(Cal);
c.BeginInvoke(null,null);
} private delegate void ExcuteCalDelegate(); private void Cal()
{
for(int i=1;i<=10000000;i++)
{
this.textBox1.Text+=(i*i).ToString()+"\r\n";
//Application.DoEvents();
}
}
使用异步委托。但是3楼的方法,在后台线程调用了UI线程的控件,这样非常危险,非常容易出现异常。在后台线程中对控件的操作,要把操作方法使用代理和空间的Invoke方法封送到后台线程,才能确保线程安全。
public partial class FormTest : Form
{
private delegate void InvokeDelegate();
private delegate void SetTextBoxHandler(TextBox tb,string str); private InvokeDelegate invokeDelegate;
private SetTextBoxHandler deleChangeText; public FormTest()
{
InitializeComponent();
} private void FormTest_Load(object sender, EventArgs e)
{
//初始化两个代理实例
this.invokeDelegate = new InvokeDelegate(this.FunTest);
this.deleChangeText = new SetTextBoxHandler(this.SetTextBoxValue);
} private void FunTest()
{
for (int i = 0; i < 100000; i++)
{
//搜索控件句柄,判断控件是否生成,不生成则返回false,此时就不能调用begininvoke方法了
//另外,如果对if内部语句的调用发生在同一线程(即UI线程或主线程),则InvokeRequired将返回false;
if (this.textBox1.InvokeRequired)
{
this.BeginInvoke(this.deleChangeText, new object[] { this.textBox1, i.ToString() });
//一定注意,Sleep的动作一定不能放在SetTextBoxValue()方法中,因为控件的BeginInvoke()会将SetTextBoxValue()方法
//封送至后台线程,这就变成了在后台线程中让主线程Sleep300ms的时间,而不是让后台线程Sleep300ms了。
Thread.Sleep(300);
}
else
{
this.SetTextBoxValue(this.textBox1, i.ToString());
Thread.Sleep(300);
}
}
} private void SetTextBoxValue(TextBox tb, string str)
{
tb.Text = str;
tb.Refresh();
//下面的句子表明,即使该方法被封送到后台线程后,该方法内的线程是主线程,而非后台线程
//MessageBox.Show(Thread.CurrentThread.IsBackground.ToString());
} //在后台线程中调用FunTest()
private void button1_Click(object sender, EventArgs e)
{
//使用异步调用,开辟后台线程
this.invokeDelegate.BeginInvoke(null, null);
}
使用DoEvent容易破坏类的结构