WinForm 多线程+委托来防止界面假死

参考: http://www.cnblogs.com/xpvincent/archive/2013/08/19/3268001.html

当有大量数据需要计算、显示在界面或者调用sleep函数时,容易导致界面卡死,可以采用多线程加委托的方法解决;

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace WindowsFormsApplication3
{
    public partial class Form1 : Form
    {
        DataTable table;
        int currentIndex = 0;
        int max = 10000;

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            buttonOK.Enabled = false;
            Thread thread = new Thread(new ThreadStart(LoadData));
            thread.IsBackground = true;
            thread.Start();

            progressBar1.Minimum = 0;
            progressBar1.Maximum = max;
        }

        private void LoadData()
        {
            SetLabelText("数据加载中...");
            currentIndex = 0;
            table = new DataTable();
            table.Columns.Add("id");
            table.Columns.Add("name");
            table.Columns.Add("age");
            while (currentIndex < max)
            {
                SetLabelText(string.Format("当前行:{0},剩余量:{1},完成比例:{2}%",
                    currentIndex, max - currentIndex, (Convert.ToDecimal(currentIndex) / Convert.ToDecimal(max) * 100).ToString()));
                SetPbValue(currentIndex);
                DataRow dr = table.NewRow();
                dr["id"] = currentIndex;
                dr["name"] = "张三";
                dr["age"] = currentIndex + 5;
                table.Rows.Add(dr);
                currentIndex++;
            }

            SetDgvDataSource(table);
            SetLabelText("数据加载完成");

            this.BeginInvoke(new MethodInvoker(delegate()
            {
                buttonOK.Enabled = true;
            }));
        }

        delegate void labDelegate(string str);
        private void SetLabelText(string str)
        {
            if (textBox1.InvokeRequired)
            {
                Invoke(new labDelegate(SetLabelText), new string[] { str });
            }
            else
            {
                textBox1.Text = str;
            }
        }

        delegate void dgvDelegate(DataTable table);
        private void SetDgvDataSource(DataTable table)
        {
            if (dataGridView1.InvokeRequired)
            {
                Invoke(new dgvDelegate(SetDgvDataSource), new object[] { table });
            }
            else
            {
                dataGridView1.DataSource = table;
            }
        }

        private delegate void pbDelegate(int value);
        private void SetPbValue(int value)
        {
            if (progressBar1.InvokeRequired)
            {
                Invoke(new pbDelegate(SetPbValue), new object[] { value });

            }
            else
            {
                progressBar1.Value = value;
            }
        }

    }
}

完整Demo下载

原文地址:https://www.cnblogs.com/runningRain/p/9215233.html

时间: 2024-08-29 23:09:49

WinForm 多线程+委托来防止界面假死的相关文章

Winform刷新时界面假死、闪烁

1.界面假死 开启新的线程做一些计算操作,只有更新控件时才委托给Form线程更新界面. 2.Winform刷新时闪烁一般的this.SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw, true);设置双缓冲.延时刷新 OCC时,机器人动作频繁刷新画面时,把form.Paint

WinForm多线程+委托防止界面卡死

1.当有大量数据需要计算.显示在界面或者调用sleep函数时,容易导致界面卡死,可以采用多线程加委托的方法解决 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.IO; using System

Qt多线程和GUI界面假死

QThread的常见特性: run()是线程的入口,就像main()对于应用程序的作用.QThread中对run()的默认实现调用了exec(),从而创建一个QEventLoop对象,由其处理该线程事件队列(每一个线程都有一个属于自己的事件队列)中的事件.简单用代码描述如下: 1 int QThread::exec() 2 { 3 //... 4 QEventLoop eventLoop; 5 int returnCode = eventLoop.exec(); 6 //... 7 return

如何防止窗口界面假死

在操作Windows.Android. Linux.IOS.Linux以及Mac OS X等系统的时候 偶尔会出现死机(宕机)的情况. 当硬件失效或者软件出错时将引起真死 此时不可等待所有冗余备用硬件或软件全部消耗完毕后再做处理, 必需立即备份数据并更换出错部件(零件)并重新引导系统硬件和软件. 当硬件和软件都完好只是系统设计不合理引起的假死那么就应当重新设计硬件和软件. 那么如何防止出现界面假死呢? 我认为要防止出现界面假死需要从以下几个方面去加强. 1.瘦界面 在设计操作系统或者应用程序时应

在wpf中利用异步lambda编程,模拟数据库连接,防止界面假死

参考<图解C#>第20章异步编程第五节程序,解决在wpf中连接数据库,界面假死问题. public partial class MainWindow : Window { private bool isConnected = false; public MainWindow() { InitializeComponent(); startWorkButton.Click += async (sender, e) => { SetGuiValues(false, "正在连接数据库

使用publisher模式控制频繁的UI输出,避免Winform界面假死

http://www.cnblogs.com/Charltsing/p/publisher.html 最近测试task并发任务的效率与线程池的区别,发现了另外一个问题.task建立任务的速度很快,输出到UI的信息过频,导致UI假死. private void TestMakeTasks(object obj) { string msg = ""; //循环创建task for (int i = 0; i < 3000; i++) { //主线程(winform)--子线程(Thr

WinForm多线程及委托防止界面假死

当有大量数据需要计算.显示在界面或者调用sleep函数时,容易导致界面卡死,可以采用多线程加委托的方法解决. using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using Syste

Delphi 多线程切换输入法后程序假死了

http://bbs.csdn.net/topics/390472740 Delphi/Pascal code ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 function TCFADODBStorage.OpenConnection: Boolean;   //线程里打开ADOConnection,在XP下切换输入法程序

winform开线程,避免页面假死

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Data.SqlClient; using System.Text.RegularExpressions;