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

之前回答了一篇关于怎么在线程中操作进度条的帖子,估计有人看的不是很明白
今天没事,写了一个小小的实例,很简单,就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. Configuring Squid as an accelerator/SSL offload for Outlook Web Access

    reference:http://wiki.squid-cache.org/SquidFaq/ReverseProxy/ Configuring Squid as an accelerator/SSL ...

  2. LCA(Tarjan)

    program LCA(Tarjan); type arr=record u,v,w,next:longint; end; ; maxm=; ..maxm*] of arr; last,lasq,an ...

  3. Unity3D ShaderLab 自定义光照模型

    接着上一篇BasicMyDiffuse的代码来说,这次要说明的就是自定义的光照模型,Ctrl+D>BasicMyDiffuse. 1.>//#pragma surface surf Lam ...

  4. HDU 4460

    http://acm.hdu.edu.cn/showproblem.php?pid=4460 水题一道,oj时间卡的非常奇怪,把spfa的queue开成全局卡线过,别的全挂了,迪杰斯特拉的手写堆都超时 ...

  5. LPEG

    local lpeg = require "lpeg"    function f0() end;    function f1() return "a" en ...

  6. 第一个Sprint冲刺事后诸葛报告

    用户反馈:软件一般般,比较传统. 用户数量:5 团队改进建议:选择题与填空题太没有新意了,需要新的创新功能. 1.每个成员第一个sprint阶段有何需要改进? 成员 需要改进 邵家文 需要更多的技术的 ...

  7. 非常基础的css注意点

    排版了很多页面,才发现自己忽视了一个很基本且重要的知识点: 一个div在一般的浏览器中,算它的width,要计算其content,padding,border. 但是在CSS中定义一个div的widt ...

  8. PAT (Basic Level) Practise:1007. 素数对猜想

    [题目链接] 让我们定义 dn 为:dn = pn+1 - pn,其中 pi 是第i个素数.显然有 d1=1 且对于n>1有 dn 是偶数.“素数对猜想”认为“存在无穷多对相邻且差为2的素数”. ...

  9. Install Fastx (zz)

    Fastx-toolkit installation on CentOS ===================================== Tested on CentOS release ...

  10. String类、正则表达式

    一.String类  String使用非常频繁,用来描述一个字符串.String中实现了很多  对字符串方便的操作方法.  String内部使用char[]实现字符串的数据保存    字符串的&quo ...