zoukankan      html  css  js  c++  java
  • 用TaskScheduler代替invoke和begininvoke异步更新那界面数据

    在异步编程时,为了更新界面的数据,经常会用invoke和begininvoke来操作。而这两个方法又必须是基于控件的,所以为了能够调用还必须传一个控件进去。而在基于任务编程时,可以使用TaskScheduler来直接更新数据。下面是代码

    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.Tasks;
    using System.Threading;
    using System.Collections.Concurrent;
    
    namespace UpdateUIData
    {
        public partial class FormMain : Form
        {
            public FormMain()
            {
                InitializeComponent();
            }
    
            Task<string> generateDataTask = null;
    
            private void buttonStart_Click(object sender, EventArgs e)
            {
                generateData();
                updateUI();
            }
    
            private void generateData()
            {
                int count = 1000;
                generateDataTask = Task.Factory.StartNew(() =>
                {
                    var data = new StringBuilder();
                    while (count > 0)
                    {
                        data.Append(count.ToString()).Append(",");
                        count--;
                    }
                    return data.ToString();
                });
            }
    
            private void updateUI()
            {
                var uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
                var updateUITask = generateDataTask.ContinueWith((t) =>
                {
                    textBoxData.Text = t.Result;
                }, uiScheduler);
            }
        }
    }
    

    由generateData开启一个任务生成数据,再由updateUI开启一个任务去更新UI数据。这里关键是用到了TaskScheduler.FromCurrentSynchronizationContext()来获取当前上下文的任务调度,然后利用它来来实现任务间对界面数据的更新。

    这样也就避免了invoke和begininvoke的使用。当然如果想要将生成的数据直接更新到界面也是可以的,下面是代码

    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.Tasks;
    using System.Threading;
    using System.Collections.Concurrent;
    
    namespace UpdateUIData
    {
        public partial class FormMain : Form
        {
            public FormMain()
            {
                InitializeComponent();
            }
    
            Task<string> generateDataTask = null;
    
            private void buttonStart_Click(object sender, EventArgs e)
            {
                // generateData();
                // updateUI();     
                generateDataToUI();
            }
    
            private void generateDataToUI()
            {
                int count = 1000;
                var uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
                Task.Factory.StartNew(() =>
                {               
                    while (count > 0)
                    {
                        textBoxData.Text += count.ToString() + ",";
                        count--;
                    }               
                }, CancellationToken.None, TaskCreationOptions.None, uiScheduler);
            }

    不过,由于数据是异步更新的,所以界面上的显示会滞后。

    如果数据更新很卡或者更新失败,可能需要在类的构造方法或者From加载时加入设置同步上下文的代码,比如

     private void FormMain_Load(object sender, EventArgs e)
            {
                SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());//If not set,update ui will be exception.           
            }
    或者
    public MyClass()
    {
     SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());//If not set,update ui will be exception.   
    }



  • 相关阅读:
    深入理解JavaScript的闭包特性 如何给循环中的对象添加事件
    兼容低版本浏览器的getElementByClassName方法
    印象深刻的bug
    pyinstaller将python编写的打卡程序打包成exe
    自动化环境搭建遇到问题
    VS2010带不出System.Data.OracleClient这个引用的解决方案
    迭代与列表生成式、生成器
    Python函数
    Python基础
    python+Selenium 环境搭建
  • 原文地址:https://www.cnblogs.com/sparkleDai/p/7605069.html
Copyright © 2011-2022 走看看