关于多线程执行显示进度条的实例!

之前回答了一篇关于怎么在线程中操作进度条的帖子,估计有人看的不是很明白
今天没事,写了一个小小的实例,很简单,就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”的线程访问它。的更多相关文章

  1. C# 委托 / 跨线程访问UI / 线程间操作无效: 从不是创建控件“Form1”的线程访问它

    C# 委托 / 跨线程访问UI /  线程间操作无效: 从不是创建控件“Form1”的线程访问它 网上的代码都比较复杂,还是这个简单 见代码, 简易解决办法: 主窗体代码 using System; ...

  2. UI多线程调用:线程间操作无效: 从不是创建控件"Form1"的线程访问它.

    有两种方式解决 1.在窗体构造函数中写Control.CheckForIllegalCrossThreadCalls =false;2.使用Invoke等委托函数. 问题原因是.net2.0以后拒绝多 ...

  3. 使用委托解决"线程间操作无效: 从不是创建控件“textBox1”的线程访问它" 问题

    在winform编程中常遇到此类问题,造成辅助线程无法给控件赋值 //定义委托 private delegate void SetTextCallback(string text); //在给text ...

  4. 关于线程间操作无效: 从不是创建控件“xx”的线程访问它,错误解决方法(自定义委托和系统委托Action或Func解决)

    这是一个线程不安全的问题.跨线程操作问题. 比如我们需要在线程中改变textbox的文本,textbox的name是txtShowMsg 第一种方法(不推荐使用) 在窗体构造函数中写Control.C ...

  5. 黄聪:C#“多线程线程间操作无效: 从不是创建控件的线程访问它。”,跨线程修改控件属性解决方案

    解决方案就是使用代理,在代理中调用主线程的方法来控制控件 /// <summary> /// 声明代理 /// </summary> delegate void SetText ...

  6. 用委托在listbox中异步显示信息,解决线程间操作无效,从不是创建控件的线程访问它

    //创建一个委托,是为访问listbox控件服务的. public delegate void UpdateTxt(string msg); //定义一个委托变量 public UpdateTxt u ...

  7. ajax实现无刷新上传附件并且显示进度条的实例

    首先:得把php.ini中的post_max_size和upload_max_filesize改成200M或更大(进度条好看效果,默认是2M) html和js代码: <!DOCTYPE html ...

  8. QT进度条QProgressBar的练习(定制QProgressBar,单独成为一个控件)

    progressbar.h #ifndef PROGRESSBAR_H #define PROGRESSBAR_H #include <QProgressBar> class QStrin ...

  9. VC下载文件 + 显示进度条

    在codeproject里找了许久,发现这样一个VC下载文件并显示进度条的源码,于是添加了些中文注释: 1.下载线程函数: UINT DownloadFile(LPVOID pParam) { CWn ...

随机推荐

  1. iOS字体设置

    label.font = [UIFont fontWithName:@"Arial-BoldItalicMT" size:24]; 字体名如下: Font Family: Amer ...

  2. 使用Inno Setup 打包.NET程序,并自动安装.Net Framework

    使用Inno Setup 打包.NET程序,并自动安装.Net Framework http://www.cnblogs.com/xiaogangqq123/archive/2012/03/19/24 ...

  3. magento -- 给后台分类管理页的分类商品加一栏商品类型

    当使用特定分类来控制前台的商品显示时,后台分类管理页的分类商品只有编号.名称.SKU和价格这几栏,选择特定商品相当不便. 可以在这里多加一栏商品类型用来筛选商品,添加的方式很简单. 打开文件/app/ ...

  4. Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面

    Android应用的开发过程中需要把繁重的任务(IO,网络连接等)放到其他线程中异步执行,达到不阻塞UI的效果. 下面将由浅入深介绍Android进行异步处理的实现方法和系统底层的实现原理. 本文介绍 ...

  5. 暴力枚举——Help Me with the Game

      Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3394   Accepted: 2172 Description You ...

  6. 递归---n皇后

    ---恢复内容开始--- #include "stdafx.h" #include <iostream> #include <fstream> //文件流 ...

  7. Debian下安装Firefox与flash简介

    Debian下安装Firefox与flash简介 由于Debian在Firefox的版权上出现了问题,导致官方发布的Debian系统不能使用默认的Firefox浏览器,最后官方重编的Firefox改名 ...

  8. 153. Find Minimum in Rotated Sorted Array

    Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 migh ...

  9. 【转】Entity Framework技术导游系列开篇与热身

    转自:http://blog.csdn.net/bitfan/article/details/12779517 Entity Framework走马观花 之 把握全局 ================ ...

  10. SQL注入测试平台 SQLol -6.CHALLENGES挑战

    SQLol上面的挑战共有14关,接下来我们一关一关来突破. Challenge 0 目的是让查询返回所有的用户名,而不是只有一个. SELECT username FROM users WHERE u ...