(委托事件处理)关于多线程执行显示进度条的实例(转)&&线程间操作无效: 从不是创建控件“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 ...
随机推荐
- React Native之生命周期
React Native生命周期主要分为三大阶段:实例化阶段(图中上框部分),存在阶段(图中左框部分),销毁阶段(图中右框部分). 如图: 下面简单讲解一下三大阶段中各自的函数: 实例化阶段: 在日常 ...
- Euro Efficiency_完全背包
Description On January 1st 2002, The Netherlands, and several other European countries abandoned the ...
- Camelot_floyd&&DP
Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 3119 Accepted: 1455 Description Centu ...
- 数据库 SQL优化
1.对查询进行优化,要尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...
- 中文圣经 for Android
中文圣经(For Android) 目前,中文圣经App包含了如下圣经版本: 和合本 现代中文译本 吕振中译本 中文新译本 英文标准本(ESV) King James Version(KJV) New ...
- 基于tcpdump实例讲解TCP/IP协议
前言 虽然网络编程的socket大家很多都会操作,但是很多还是不熟悉socket编程中,底层TCP/IP协议的交互过程,本文会一个简单的客户端程序和服务端程序的交互过程,使用tcpdump抓包,实例讲 ...
- Cocos2d-x 网络资源
blog: http://www.cnblogs.com/mmidd/tag/Cocos2d-x/ http://blog.csdn.net/u012945598
- jconsole远程查看jvm性能
Java VisualVM -- JDK自带的强大性能监测工具 这里给出了另一种,可以通过jdk下bin目录下的jconsole.exe来观察java程序内存的使用及变化情况 一般远程调试可以用,性能 ...
- 浅谈github页面域名绑定
来源:http://yanping.me/cn/blog/2011/12/04/github-pages-domain/ 前段时间看到COS上的各位都有博客,也想开个博,给COS的各位管理员发邮件,向 ...
- 高逼格的画图:VIM原来可以这样玩
在Linux上其实并不缺少画图软件(比如yEd等),那么为什么还需要用VIM来画图: 更轻,不需要安装太多东西 更小,就是一些文本,比图片什么的小多了,使用起来也更简单 更有逼格 那么我们该怎么做呢? ...