(委托事件处理)关于多线程执行显示进度条的实例(转)&&线程间操作无效: 从不是创建控件“rtxtEntryNO”的线程访问它。
之前回答了一篇关于怎么在线程中操作进度条的帖子,估计有人看的不是很明白
今天没事,写了一个小小的实例,很简单,就2个文件
权当抛砖引玉,希望有更好解决方案的人发表一下意见
界面上2个控件,一个按钮和一个进度条
using System;
using System.Threading;
using System.Windows.Forms;
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//线程开始的时候调用的委托
private delegate void maxValueDelegate(int maxValue);
//线程执行中调用的委托
private delegate void nowValueDelegate(int nowValue);
private void button1_Click(object sender, EventArgs e)
{
ThreadMethod method = new ThreadMethod();
//先订阅一下事件
method.threadStartEvent += new EventHandler(method_threadStartEvent);
method.threadEvent += new EventHandler(method_threadEvent);
method.threadEndEvent += new EventHandler(method_threadEndEvent);
Thread thread = new Thread(new ThreadStart(method.runMethod));
thread.Start();
}
/// <summary>
/// 线程完成事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void method_threadEndEvent(object sender, EventArgs e)
{
MessageBox.Show("我完成啦!");
}
/// <summary>
/// 线程执行中的事件,设置进度条当前进度
/// 但是我不能直接操作进度条,需要一个委托来替我完成
/// </summary>
/// <param name="sender">ThreadMethod函数中传过来的当前值</param>
/// <param name="e"></param>
void method_threadEvent(object sender, EventArgs e)
{
int nowValue = Convert.ToInt32(sender);
nowValueDelegate now = new nowValueDelegate(setNow);
this.Invoke(now, nowValue);
}
/// <summary>
/// 线程开始事件,设置进度条最大值
/// 但是我不能直接操作进度条,需要一个委托来替我完成
/// </summary>
/// <param name="sender">ThreadMethod函数中传过来的最大值</param>
/// <param name="e"></param>
void method_threadStartEvent(object sender, EventArgs e)
{
int maxValue = Convert.ToInt32(sender);
maxValueDelegate max = new maxValueDelegate(setMax);
this.Invoke(max, maxValue);
}
/// <summary>
/// 我被委托调用,专门设置进度条最大值的
/// </summary>
/// <param name="maxValue"></param>
private void setMax(int maxValue)
{
this.progressBar1.Maximum = maxValue;
}
/// <summary>
/// 我被委托调用,专门设置进度条当前值的
/// </summary>
/// <param name="nowValue"></param>
private void setNow(int nowValue)
{
this.progressBar1.Value = nowValue;
}
}
}
另外一个文件
using System;
using System.Threading;
namespace WindowsFormsApplication2
{
/// <summary>
/// 线程处理方法
/// </summary>
public class ThreadMethod
{
/// <summary>
/// 线程开始事件
/// </summary>
public event EventHandler threadStartEvent;
/// <summary>
/// 线程执行时事件
/// </summary>
public event EventHandler threadEvent;
/// <summary>
/// 线程结束事件
/// </summary>
public event EventHandler threadEndEvent;
public void runMethod()
{
int count = 100; //执行多少次
threadStartEvent.Invoke(count, new EventArgs());//通知主界面,我开始了,count用来设置进度条的最大值
for (int i = 0; i < count; i++)
{
Thread.Sleep(100);//休息100毫秒,模拟执行大数据量操作
threadEvent.Invoke(i, new EventArgs());//通知主界面我正在执行,i表示进度条当前进度
}
threadEndEvent.Invoke(new object(), new EventArgs());//通知主界面我已经完成了
}
}
}
对于“线程间操作无效: 从不是创建控件“rtxtEntryNO”的线程访问它。”问题可以使用Invoke等委托解决:
//线程正在运行时候调用的委托
private delegate void nowValueDelegate(int nowValue);
private delegate void nowStatusDelegate(string nowStatus);
//线程开始的时候调用的委托
private delegate void startDelegate();
private delegate void maxValueDelegate(int maxValue);
//线程结束的时候调用的委托
private delegate void endDelegate();
/// <summary>
/// 被委托调用,专门设置进度条当前值的
/// </summary>
/// <param name="nowValue"></param>
private void setNow(int nowValue)
{
this.progressBar1.Value = nowValue;
lblCurrentAmount.Text = "当前已比对" + nowValue + "条数据";
}
/// <summary>
/// 被委托调用,专门设置进度条最大值
/// </summary>
/// <param name="nowValue"></param>
private void setTotal(int total)
{
this.progressBar1.Maximum = total;
this.lblTotal.Text = "共" + total + "条数据";
}
/// <summary>
/// 被委托调用,专门设置当前状态
/// </summary>
/// <param name="nowValue"></param>
private void setStatus(string nowStatus)
{
this.lblCurrentStatus.Text = nowStatus;
}
/// <summary>
/// 当线程执行完毕后被委托调用的方法
/// </summary>
/// <param name="nowValue"></param>
private void EndThread()
{
this.panel1.Visible = false;
}
/// <summary>
/// 当线程开始时被委托调用的方法
/// </summary>
/// <param name="nowValue"></param>
private void StartThread()
{
this.panel1.Visible = true;
lblCurrentStatus.Text = "正在查询数据…";
}
//进程开始时调用的委托
startDelegate startThread=new startDelegate(StartThread);
this.Invoke(startThread);
//委托设置进度当前状态
nowStatusDelegate status0 = new nowStatusDelegate(setStatus);
this.Invoke(status0, "正在查询数据…");
Application.DoEvents(); //在循环体中即使改变了进度条的相关数值也不能实现刷新(消息队列是循环结束后一起发送出去的),所以利用Application.DoEvents();实现实时发送。
//委托设置进度当前状态
nowStatusDelegate status = new nowStatusDelegate(setStatus);
this.Invoke(status, "正在比对数据…");
Application.DoEvents();
(委托事件处理)关于多线程执行显示进度条的实例(转)&&线程间操作无效: 从不是创建控件“rtxtEntryNO”的线程访问它。的更多相关文章
- C# 委托 / 跨线程访问UI / 线程间操作无效: 从不是创建控件“Form1”的线程访问它
C# 委托 / 跨线程访问UI / 线程间操作无效: 从不是创建控件“Form1”的线程访问它 网上的代码都比较复杂,还是这个简单 见代码, 简易解决办法: 主窗体代码 using System; ...
- UI多线程调用:线程间操作无效: 从不是创建控件"Form1"的线程访问它.
有两种方式解决 1.在窗体构造函数中写Control.CheckForIllegalCrossThreadCalls =false;2.使用Invoke等委托函数. 问题原因是.net2.0以后拒绝多 ...
- 使用委托解决"线程间操作无效: 从不是创建控件“textBox1”的线程访问它" 问题
在winform编程中常遇到此类问题,造成辅助线程无法给控件赋值 //定义委托 private delegate void SetTextCallback(string text); //在给text ...
- 关于线程间操作无效: 从不是创建控件“xx”的线程访问它,错误解决方法(自定义委托和系统委托Action或Func解决)
这是一个线程不安全的问题.跨线程操作问题. 比如我们需要在线程中改变textbox的文本,textbox的name是txtShowMsg 第一种方法(不推荐使用) 在窗体构造函数中写Control.C ...
- 黄聪:C#“多线程线程间操作无效: 从不是创建控件的线程访问它。”,跨线程修改控件属性解决方案
解决方案就是使用代理,在代理中调用主线程的方法来控制控件 /// <summary> /// 声明代理 /// </summary> delegate void SetText ...
- 用委托在listbox中异步显示信息,解决线程间操作无效,从不是创建控件的线程访问它
//创建一个委托,是为访问listbox控件服务的. public delegate void UpdateTxt(string msg); //定义一个委托变量 public UpdateTxt u ...
- ajax实现无刷新上传附件并且显示进度条的实例
首先:得把php.ini中的post_max_size和upload_max_filesize改成200M或更大(进度条好看效果,默认是2M) html和js代码: <!DOCTYPE html ...
- QT进度条QProgressBar的练习(定制QProgressBar,单独成为一个控件)
progressbar.h #ifndef PROGRESSBAR_H #define PROGRESSBAR_H #include <QProgressBar> class QStrin ...
- VC下载文件 + 显示进度条
在codeproject里找了许久,发现这样一个VC下载文件并显示进度条的源码,于是添加了些中文注释: 1.下载线程函数: UINT DownloadFile(LPVOID pParam) { CWn ...
随机推荐
- 【Oracle XE系列之三】使用OMF方式手工创建Oracle XE数据库
环境:win10_X64_Pro 1.创建数据库实例,实例名为PF C:\oraclexe\app\oracle\product\11.2.0\server\bin>oradim -new -s ...
- JS手机定位地理位置
/** * 以下为html5代码,获取地理位置 */ /** * 设置地址 */ function setAddress(json) { var position = document.getElem ...
- HDU 1350
http://acm.hdu.edu.cn/showproblem.php?pid=1350 给m个顾客的乘车信息,表示几点前上车,要从一个坐标点到达另一个坐标点,花费的时间是两点的曼哈顿距离,两次换 ...
- Inno如何在安装完成时删除指定的文件夹(下的所有文件及子目录)??
删除安装目录下的任意文件夹及下的所有文件及子目录,或者删除指定目录的文件夹,要如何做到呢?谢谢!! //删除文件 用 DeleteFile 只能删除一个文件,不能使用通配符来删除多个文件Dele ...
- iOS平台XML解析类库对比和安装说明
在iPhone开发中,XML的解析有很多选择,iOS SDK提供了NSXMLParser和libxml2两个类库,另外还有很多第三方类库可选,例如TBXML.TouchXML.KissXML.Tiny ...
- (实用篇)php精确的统计在线人数的方法
这是一个非常精确的,通过php实现统计在线人数的方法,想知道怎么实现的请耐心阅读. <?php $filename='online.txt';//数据文件 $cookiename='VGOTCN ...
- SFTP 上传文件夹
使用sftp上传文件夹时若使用如下命令并不work: put /media/Research/GWAS_Class/* Desktop/ 此时,需要添加一个参数 -r, 另外在目标文件夹下面建立一个同 ...
- 如何为libs目录下的jar包关联源代码
以前,我们可以为lib目录下的jar包关联源代码,但是现在似乎不行了. 下面是一篇讲述此问题解决方法的文章: How to attach javadoc or sources to jars in l ...
- ASP连接access 数据库的增删改查 - imsoft.cnblogs
假设数据库文件名叫data.mdb里面有2个表:1.admin2.news假设admin是保存用户名和密码,里面有字段:UserName,PassWord.假设我们要在判断一个用户名叫name,密码是 ...
- UI学习笔记---第八天
UINavigationController的用法 界面间传值 UInavigationController继承于UIViewController,以栈的方式管理所控制的师徒控制器,至少要有一个被 ...