(委托事件处理)关于多线程执行显示进度条的实例(转)&&线程间操作无效: 从不是创建控件“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 ...
随机推荐
- java作业4
(一) 请查看String.equals()方法的实现代码,注意学习其实现方法.(发表到博客作业上) (二) 整理String类的Length().charAt(). getChars().rep ...
- WCF客户端和服务端配置
服务端: <system.serviceModel> <services> <service name="Microsoft.ServiceModel.Samp ...
- Nunit 使用介绍
Nunit是.NET平台单元测试框架,其是从Junit发展而来,它强大之处是支持所有的.NET语言. Nunit的下载地址:http://www.nunit.org 介绍1: 布局: 左面:我们写的每 ...
- MINIX3 保护模式分析
3.1 INTEL 保护模式概要 先要说明一个问题:不是 MINIX3 一定要设置这个保护模式,但是在 386 平台上, 引入了这个保护模式机制,MINIX3 不得不设立相关保护模式的内容.由于 38 ...
- 即使连网了ping也会失败
/*************************************************************************** * 即使连网了ping也会失败 * 说明: * ...
- Core Java Volume I — 4.4. Static Fields and Methods
4.4. Static Fields and MethodsIn all sample programs that you have seen, the main method is tagged w ...
- 使用apt-get方式为Kubuntu安装PHP+MYSQL+Apache
相信很多搭过动态网站的朋友都知道怎么搭web服务器, 本人是linux新手, 以前在windows是直接使用集成的wamp server, 所以在linux没有亲手搭过. 本系统: ubuntu 12 ...
- Apache CXF 103 CXF Basics - partial
本Spike记录中内容,如无特别指出,均引用[1]. 0 引言 0.1 基本的Web服务术语 XML 业界的结构化交换信息表示的事实上的标准. XML namespace是在XML文档中提供唯一的命名 ...
- codeforces magic five --快速幂模
题目链接:http://codeforces.com/contest/327/problem/C 首先先算出一个周期里面的值,保存在ans里面,就是平常的快速幂模m做法. 然后要计算一个公式,比如有k ...
- Bootstrap部分---环境安装及一个可视化的布局;
一:环境安装*****顺序不可变***** <head> 如果需要可以设定,移动设备优先 <meta name="viewport" content=" ...