zoukankan      html  css  js  c++  java
  • 多线程更新UI的常用方法

         开发Winform或者WPF相关GUI程序中,遇到执行耗时程序片段,并且需要在ui界面上实时展示状态信息的问题时,为了防止界面出现假死状态,会用到多线程技术,异步跨线程访问ui界面元素;下面总结下Winform和WPF中常用的几种异步跨线程访问ui界面的技术。

    Winform中常用技术

     1、采用BackgroundWorker控件

    public partial class Form1 : Form
        {
            private BackgroundWorker worker;
            public Form1()
            {
                InitializeComponent();
                worker = new BackgroundWorker();
                worker.WorkerReportsProgress = true;// To report progress from the background worker we need to set this property
                worker.DoWork += worker_DoWork;// This event will be raised on the worker thread when the worker starts
                worker.ProgressChanged += worker_ProgressChanged;// This event will be raised when we call ReportProgress
            }
    
            private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
            {
                progressBar1.Value = e.ProgressPercentage;
                lblPercent.Text = string.Format("{0}%", e.ProgressPercentage);
                if (e.ProgressPercentage == 100)
                {
                    MessageBox.Show("数据处理完毕!");
                }
            }
    
            private void worker_DoWork(object sender, DoWorkEventArgs e)
            {
                for (int i = 1; i <= 100; i++)
                {
                    // Report progress to 'UI' thread
                    worker.ReportProgress(i);
                    Thread.Sleep(100);
                }
            }
    
            private void btnCompute_Click(object sender, EventArgs e)
            {
                //Start the background worker
                worker.RunWorkerAsync();
            }
        }

    2、采用Timer控件

    public partial class Form1 : Form
        {
            private Timer timer;
            private int current;
            public Form1()
            {
                InitializeComponent();
                timer = new Timer();
                timer.Interval = 500;
                timer.Tick += timer_Tick;
            }
    
            private void timer_Tick(object sender, EventArgs e)
            {
                progressBar1.Value = current;
                lblPercent.Text = string.Format("{0}%", current);
                if (current == 100)
                {
                    timer.Stop();
                    MessageBox.Show("数据处理完毕!");
                }
            }
    
            private void btnCompute_Click(object sender, EventArgs e)
            {
                Thread thread = new Thread(new ThreadStart(doWork));
                thread.Start();
                timer.Start();
            }
    
            private void doWork()
            {
                for (int i = 1; i <= 100; i++)
                {
                    current = i;
                    Thread.Sleep(100);
                }
            }
        }

    3、采用委托的方式

    public partial class Form1 : Form
        {
            private delegate void UpdateProgress(int percent);
            public Form1()
            {
                InitializeComponent();
            }
    
            private void btnCompute_Click(object sender, EventArgs e)
            {
                Thread thread = new Thread(new ThreadStart(doWork));
                thread.Start();
            }
    
            private void doWork()
            {
                for (int i = 1; i <= 100; i++)
                {
                    //progressBar1.BeginInvoke((Action)(() => { progressBar1.Value = i; }));
                    //lblPercent.BeginInvoke((Action)(() => { lblPercent.Text = string.Format("{0}%", i); }));
                    //if (i == 100)
                    //{
                    //    MessageBox.Show("数据处理完毕!");
                    //}
                    update(i);
                    Thread.Sleep(100);
                }
            }
    
            private void update(int percent)
            {
                if (InvokeRequired)
                {
                    this.Invoke(new UpdateProgress(update), percent);
                }
                else
                {
                    progressBar1.Value = percent;
                    lblPercent.Text = string.Format("{0}%", percent);
                    if (percent == 100)
                    {
                        MessageBox.Show("数据处理完毕!");
                    }
                }
            }
        }

    WPF中常用技术

         WPF中引入了Dispatcher,常用来解决非ui线程中更新ui控件状态的问题。

    /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
            private delegate void UpdateProgress(int percent);
            public MainWindow()
            {
                InitializeComponent();
            }
    
            private void BtnCompute_OnClick(object sender, RoutedEventArgs e)
            {
                Task task = new Task(DoWork);
                task.Start();
            }
    
            private void DoWork()
            {
                for (int i = 1; i <= 100; i++)
                {
                    //Dispatcher.BeginInvoke((Action)(() =>
                    //{
                    //    progressBar1.Value = i;
                    //    lblPercent.Content = string.Format("{0}%", i);
                    //    if (i == 100)
                    //    {
                    //        MessageBox.Show("数据处理完毕!");
                    //    }
                    //}));
                    Dispatcher.BeginInvoke(new UpdateProgress(Update), i);
                    Thread.Sleep(100);
                }
            }
    
            private void Update(int percent)
            {
                progressBar1.Value = percent;
                lblPercent.Content = string.Format("{0}%", percent);
                if (percent == 100)
                {
                    MessageBox.Show("数据处理完毕!");
                }
            }
        }

    作者:HarderQian

    出处:http://www.cnblogs.com/harderqian

    说明:文章为作者平时里的思考和练习,可能有不当之处,请博客园的园友们多提宝贵意见。

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.

  • 相关阅读:
    使用 v-cloak 防止页面加载时出现 vuejs 的变量名
    Jackson 解析json数据之忽略解析字段注解@JsonIgnoreProperties
    java.lang.IllegalStateException: Cannot run without an instance id.
    沪牌-上海牌照-拍牌经验分享: 我是如何三次拍中的?
    沪牌学院-沪拍拍课堂4: 实拍前的演练
    沪牌学院-沪拍拍课堂3: 网络优化
    沪牌学院-沪拍拍课堂2: 出价策略
    沪牌学院-沪拍拍课堂1: 估价策略
    如何将 DVD 转成 ISO
    雅虎天气-城市代码列表
  • 原文地址:https://www.cnblogs.com/harderqian/p/5588667.html
Copyright © 2011-2022 走看看