C# 委托实现多线程调用窗体

1、第一种方法:使用线程

功能描述:在用C#做WinFrom开发的过程中。我们经常需要用到进度条(ProgressBar)用于显示进度信息。这时候我们可能就需要用到多线程,如果不采用多线程控制进度条,窗口很容易假死(无法适时看到进度信息)。下面我就简单结合一个我写的例子给大家做一个介绍。
这里写图片描述
控件名称分别为:progressBar1;label1;richTextBox1;button1;
实现代码:

using System;
using System.Threading;
using System.Windows.Forms;

namespace Test1
{
    public partial class Form1 : Form
    {
        /// <summary>
        /// 定义一个委托,用于更新ProgressBar的值(Value)及在执行方法的时候,返回方法的处理信息。
        /// </summary>
        /// <param name="ipos"></param>
        /// <param name="vinfo"></param>
        private delegate void SetPos(int ipos, string vinfo);//代理

        public Form1()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 进度条值更新函数(参数必须跟声明的代理参数一样)
        /// </summary>
        /// <param name="ipos"></param>
        /// <param name="vinfo"></param>
        private void SetTextMessage(int ipos, string vinfo)
        {
            if (this.InvokeRequired)
            {
                SetPos setPos = new SetPos(SetTextMessage);
                this.Invoke(setPos, new object[] { ipos, vinfo });
            }
            else
            {
                this.label1.Text = ipos + "/1000";
                this.progressBar1.Value = Convert.ToInt32(ipos);
                this.richTextBox1.AppendText(vinfo);
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Thread fThread = new Thread(new ThreadStart(SleepT));
            fThread.Start();
        }

        /// <summary>
        /// 新的线程执行函数
        /// </summary>
        private void SleepT()
        {
            for (int i = 0; i < 500; i++)
            {
                Thread.Sleep(10);
                SetTextMessage(100 * i / 500, i + "\r\n");
            }
        }
    }
}

实现效果:
这里写图片描述

2、第二种方法

功能描述:该种方法通过控件backgroundWorker1实现进度条,进度条在一个模板窗体内。
主窗体设计:button1;backgroundWorker1;
这里写图片描述
进度条窗体设计:progressBar1;button1
这里写图片描述
主窗体实现代码:

using System.ComponentModel;
using System.Threading;
using System.Windows.Forms;

namespace Test2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, System.EventArgs e)
        {
            backgroundWorker1.RunWorkerAsync();//运行backgroundWorker组件

            ProcessForm processForm = new ProcessForm(backgroundWorker1);//显示进度条窗体
            processForm.ShowDialog(this);
            processForm.Close();
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                MessageBox.Show(e.Error.Message);
            }
        }

        /// <summary>
        /// 实现调用,方法等
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;
            for (int i = 0; i < 100; i++)
            {
                Thread.Sleep(100);
                worker.ReportProgress(i);
                if (worker.CancellationPending)//如果用户取消则跳出数据代码
                {
                    e.Cancel = true;
                    break;
                }
            }
        }
    }
}

进度条窗体:

using System.ComponentModel;
using System.Windows.Forms;

namespace Test2
{
    public partial class ProcessForm : Form
    {
        private BackgroundWorker backgroundWorker1;// //ProcessForm 窗体事件(进度条窗体)

        public ProcessForm(BackgroundWorker backgroundWorker1)
        {
            InitializeComponent();
            this.backgroundWorker1 = backgroundWorker1;
            this.backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
            this.backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            this.Close();//执行完之后,直接关闭界面
        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBar1.Value = e.ProgressPercentage;
        }

        /// <summary>
        /// 取消按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, System.EventArgs e)
        {
            backgroundWorker1.CancelAsync();
            button1.Enabled = false;
            Close();
        }
    }
}

3、第三种方法

功能描述:在处理大量数据的时候,有时候方法的执行需要一定的时间,这时候往往会造成页面或程序的“假死”状态,给用户的体验度也不是很好。为了避免出现“假死”提高用户的体验度,在这里为这类型的方法加了一个进度条和一个文本框,进度条用于显示程序处理的进度,文本框用于显示在处理过程中,给与的提示。本方法主要使用了控件:backgroundWorker1;说明:本方法与上面的方法(方法二)基本类型,主要是设计和代码进行了一些修改。
主窗体设计:button1;backgroundWorker1;
这里写图片描述
对backgroundWorker1控件,属性设置:
这里写图片描述
主窗口后台代码:

using System.ComponentModel;
using System.Threading;
using System.Windows.Forms;

namespace Test3
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, System.EventArgs e)
        {
            this.backgroundWorker1.RunWorkerAsync();//运行 backgroundWorker 组件

            ProcessForm processForm = new ProcessForm(backgroundWorker1);
            processForm.ShowDialog(this);
            processForm.Close();
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                MessageBox.Show(e.Error.Message);
            }
        }

        /// <summary>
        /// 实现调用,方法等
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;
            for (int i = 0; i < 100; i++)
            {
                Thread.Sleep(100);
                worker.ReportProgress(i, i + "你好!\r\n"); //注意:这里向子窗体返回信息值,这里是两个值,一个用于进度条,一个用于文本框的。
                if (worker.CancellationPending)  //如果用户取消则跳出处理数据代码 
                {
                    e.Cancel = true;
                    break;
                }
            }
        }
    }
}

子窗体后台代码:

using System.ComponentModel;
using System.Windows.Forms;

namespace Test3
{
    public partial class ProcessForm : Form
    {
        private BackgroundWorker backgroundWorker1;//ProcessForm 窗体事件(进度条窗体)

        public ProcessForm(BackgroundWorker backgroundWorker1)
        {
            InitializeComponent();

            this.backgroundWorker1 = backgroundWorker1;
            this.backgroundWorker1.ProgressChanged +=  backgroundWorker1_ProgressChanged;
            this.backgroundWorker1.RunWorkerCompleted += backgroundWorker1_RunWorkerCompleted;
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            //this.Close();//执行完之后,直接关闭窗口
        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBar1.Value = e.ProgressPercentage;
            //richTextBox1.AppendText(e.UserState.ToString());//主窗体传过来的值,通过e.UserState.ToString()来接受
            richTextBox1.Text += e.UserState.ToString();
        }

        private void button1_Click(object sender, System.EventArgs e)
        {
            backgroundWorker1.CancelAsync();
            button1.Enabled = false;
            Close();
        }
    }
}

注意:如果在程序为执行完,就点击取消的话,很有可能会报错的,这时候,你就修改一个方法:backgroundWorker1_ProgressChanged
如下:

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBar1.Value = e.ProgressPercentage;
            //richTextBox1.AppendText(e.UserState.ToString());//主窗体传过来的值,通过e.UserState.ToString()来接受
            richTextBox1.Text += e.UserState.ToString();
        }

4、第四种方法:

功能描述:本方法实现进度条显示,方法执行信息反馈显示。用到的技术点为 线程与代理。
主窗口设计:button1;
这里写图片描述
子窗口设计:progressBar1;richtextBox1
这里写图片描述
主窗口后台代码:

using System.Threading;
using System.Windows.Forms;

namespace Test4
{
    public partial class Form1 : Form
    {
        private Form2 _myProcessBar;//弹出的子窗体(用于显示进度条)
        private delegate bool IncreaseHandle(int nValue, string ninfo);//创建委托
        private IncreaseHandle _myIncrease;//声明委托,用于后面的实例化委托
        private int vMax = 100;//用于实例化进度条,可以根据自己的需要,自己改变

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, System.EventArgs e)
        {
            Thread thdSub = new Thread(ThreadFun);
            thdSub.Start();
        }

        private void ThreadFun()
        {
            MethodInvoker mi = new MethodInvoker(ShowProcessBar);
            BeginInvoke(mi);
            Thread.Sleep(100);
            object objReturn = null;
            for (int i = 0; i < vMax; i++)
            {
                objReturn = Invoke(_myIncrease, new object[] { 2, i + "\r\n" });
                Thread.Sleep(50);
            }
        }

        private void ShowProcessBar()
        {
            _myProcessBar = new Form2(vMax);
            _myIncrease = new IncreaseHandle(_myProcessBar.Increase);
            _myProcessBar.ShowDialog();
            _myProcessBar = null;
        }
    }
}

子窗口后台代码:

using System;
using System.Windows.Forms;

namespace Test4
{
    public partial class Form2 : Form
    {
        public Form2(int vMax)
        {
            InitializeComponent();
            this.progressBar1.Maximum = vMax;
        }

        public bool Increase(int nvalue, string ninfo)
        {
            if (nvalue > 0)
            {
                if (progressBar1.Value + nvalue < progressBar1.Maximum)
                {
                    progressBar1.Value += nvalue;
                    richTextBox1.AppendText(ninfo);
                    Application.DoEvents();
                    progressBar1.Update();
                    progressBar1.Refresh();
                    richTextBox1.Update();
                    richTextBox1.Refresh();
                    return true;
                }
                else
                {
                    progressBar1.Value = progressBar1.Maximum;
                    richTextBox1.AppendText(ninfo);
                    //this.Close();//执行完之后,自动关闭子窗体
                    return false;
                }
            }
            return false;
        }
    }
}
已标记关键词 清除标记
课程简介: 历经半个多月的时间,Debug亲自撸的 “企业员工角色权限管理平台” 终于完成了。正如字面意思,本课程讲解的是一个真正意义上的、企业级的项目实战,主要介绍了企业级应用系统中后端应用权限的管理,其中主要涵盖了六大核心业务模块、十几张数据库表。 其中的核心业务模块主要包括用户模块、部门模块、岗位模块、角色模块、菜单模块和系统日志模块;与此同时,Debug还亲自撸了额外的附属模块,包括字典管理模块、商品分类模块以及考勤管理模块等等,主要是为了更好地巩固相应的技术栈以及企业应用系统业务模块的开发流程! 核心技术栈列表: 值得介绍的是,本课程在技术栈层面涵盖了前端和后端的大部分常用技术,包括Spring Boot、Spring MVC、Mybatis、Mybatis-Plus、Shiro(身份认证与资源授权跟会话等等)、Spring AOP、防止XSS攻击、防止SQL注入攻击、过滤器Filter、验证码Kaptcha、热部署插件Devtools、POI、Vue、LayUI、ElementUI、JQuery、HTML、Bootstrap、Freemarker、一键打包部署运行工具Wagon等等,如下图所示: 课程内容与收益: 总的来说,本课程是一门具有很强实践性质的“项目实战”课程,即“企业应用员工角色权限管理平台”,主要介绍了当前企业级应用系统中员工、部门、岗位、角色、权限、菜单以及其他实体模块的管理;其中,还重点讲解了如何基于Shiro的资源授权实现员工-角色-操作权限、员工-角色-数据权限的管理;在课程的最后,还介绍了如何实现一键打包上传部署运行项目等等。如下图所示为本权限管理平台的数据库设计图: 以下为项目整体的运行效果截图: 值得一提的是,在本课程中,Debug也向各位小伙伴介绍了如何在企业级应用系统业务模块的开发中,前端到后端再到数据库,最后再到服务器的上线部署运行等流程,如下图所示:
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页