当前位置:首页 > C# > 正文内容

c# 委托实现多线程的实例/另一个class类调用控件

admin3年前 (2021-09-27)C#3059

一、使用线程在窗体中显示进度条

在Winform应用程序中,经常用进度条显示进度信息。这时候就可能用到多线程。如果不采用多线程控制进度条的话,窗口界面很容易假死(无法看到进度信息,看起来像界面卡住了)。
在这个实例中,我们建立一个窗体,窗体中包括一个后台组件,一个进度条控件。当在主窗体中按“开始”按钮时,进度条开始显示进度。
该实例中用Backgroundworker组件,表示后台工作。通过后台工作组件实现进度条。
主窗体:

进度条窗体:

进度条窗体的代码如下:



    public partial class ProcessForm : Form
    {
        //后台操作
        private BackgroundWorker backgroundworker1;
        public ProcessForm(BackgroundWorker backgroundworker1)
        {
            InitializeComponent();
            this.backgroundworker1 = backgroundworker1;
            this.backgroundworker1.ProgressChanged += new ProgressChangedEventHandler(backgroundworker1_ProcessChanged);
            this.backgroundworker1.RunWorkerCompleted +=new RunWorkerCompletedEventHandler( Backgroundworker1_RunWorkerCompleted);
        }
        /// <summary>
        /// 当辅助线程完成时引发
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Backgroundworker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            this.Close();
        }

        private void backgroundworker1_ProcessChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBar1.Value = e.ProgressPercentage;//异步任务的进度百分比

        }

        private void button1_Click(object sender, EventArgs e)
        {
            backgroundworker1.WorkerSupportsCancellation = true;
            backgroundworker1.CancelAsync();
            button1.Enabled = false;
            Close();
        }
    }
主窗体代码如下:




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

        private void btnBegin_Click(object sender, EventArgs e)
        {
            backgroundWorker1.RunWorkerAsync();//开始执行后台操作
            ProcessForm pf = new ProcessForm(backgroundWorker1);//显示进度条窗体,将后台程序传给进度条窗体
            pf.ShowDialog(this);
            pf.Close();
        }

        /// <summary>
        /// 当辅助线程完成时引发
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        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.WorkerReportsProgress = true;
                worker.ReportProgress(i);
                if(worker.CancellationPending)
                {
                    e.Cancel = true;
                    break;
                }
            }
        }
    }



运行结果:

该例是通过后台程序组件完成对进度条的展示。
也可以在主窗体中通过后台组件完成进度条的显示,窗体设计如下:

代码如下:


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

        private void btnBegin_Click(object sender, EventArgs e)
        {
            backgroundWorker1.RunWorkerAsync();//开始执行后台操作

        }

        /// <summary>
        /// 当辅助线程完成时引发
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                MessageBox.Show(e.Error.Message);
            }
            GC.Collect();
        }

        /// <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<101;i++)
            {
                Thread.Sleep(100);
                worker.WorkerReportsProgress = true;
                worker.ReportProgress(i);
                BeginInvoke(new Action(() =>
                {
                    label1.Text = progressBar1.Value.ToString();
                }));

                if(worker.CancellationPending)
                {
                    e.Cancel = true;
                    break;
                }
            }
            BeginInvoke(new Action(() =>
            {
                label1.Text = "完成";
            }));
        }
        /// <summary>
        /// 取消
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            backgroundWorker1.WorkerSupportsCancellation = true;
            backgroundWorker1.CancelAsync();
            button1.Enabled = false;
            Close();
        }

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





运行结果如下:

二、实例二

功能说明:有时候在处理大量数据的时候,有时候方法的执行需要一定的时间,这时候往往会造成页面或程序的假死状态,对于用户的体验度也很不好。为了避免这种情况的发生,我们可以加一个进度条和一个文本框。来显示程序处理的进度。




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

        private void btnBegin_Click(object sender, EventArgs e)
        {
            backgroundWorker1.RunWorkerAsync();//开始执行后台操作

        }

        /// <summary>
        /// 当辅助线程完成时引发
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                MessageBox.Show(e.Error.Message);
            }
            GC.Collect();
        }

        /// <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<101;i++)
            {
                Thread.Sleep(100);
                //报告进度的属性设为true,允许报告进度
                worker.WorkerReportsProgress = true;
                worker.ReportProgress(i,i+"你好!\r\n");


                if(worker.CancellationPending)
                {
                    e.Cancel = true;
                    break;
                }
            }

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

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBar1.Value = e.ProgressPercentage;
            label1.Text += e.UserState.ToString();
        }
    }




扫描二维码推送至手机访问。

版权声明:本文由视觉博客发布,如需转载请注明出处。

本文链接:https://feelsight.cn/post/124.html

“c# 委托实现多线程的实例/另一个class类调用控件” 的相关文章

c#打开txt文件并导入到textbox中

OpenFileDialog openFileDialog = new OpenFileDialog();             ope...

C#获取机器码的方法详解(机器名,CPU编号,硬盘编号,网卡mac等)

这篇文章主要介绍了C#获取机器码的方法,结合实例形式详细分析了C#获取硬件机器名、CPU编号、硬盘编号、网卡mac等信息的相关实现方法,需要的朋友可以参考下本文实例讲述了C#获取机器码的方法。分享给大家供大家参考,具体如下:using System.Runtime.InteropServi...

 C#图像处理(各种旋转、改变大小、柔化、锐化、雾化、底片、浮雕、黑白、滤镜效果)

C#图像处理(各种旋转、改变大小、柔化、锐化、雾化、底片、浮雕、黑白、滤镜效果)

一、各种旋转、改变大小 注意:先要添加画图相关的using引用。 //向右旋转图像90°代码如下: private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e) {...

安装包制作工具 SetupFactory使用2 API清单

安装包制作工具 SetupFactory使用2 API清单

SetupFactory中可以通过其API控制很复杂的业务需求。   下图中展示了其内置的API种类与具体分类函数。             ...

C#中的MessageBox消息对话框

C#中的MessageBox消息对话框

在程序中,我们经常使用消息对话框给用户一定的信息提示,如在操作过程中遇到错误或程序异常,经常会使用这种方式给用于以提示。在C#中,MessageBox消息对话框位于System.Windows.Forms命名空间中,一般情况,一个消息对话框包含信息提示文字内容、消息对话框的标题文字、用户响应的...

C# 窗体间传值(Form与From之间互相传值)

C# 窗体间传值(Form与From之间互相传值)

1、委托   两个窗体,窗体很简单,只实现改变颜色功能,一看就会: 代码如下,只贴按钮事件代码: 打开Form2按钮事件 private void button1_Click(object s...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。