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.   
    }



  • 相关阅读:
    Poj2155Matrix二维线段树
    二维树状数组模板
    PAT-1014 Waiting in Line (30 分) 优先队列
    PAT-1012 The Best Rank (25 分) 查询分数对应排名(包括并列)
    PAT-1003 Emergency (25 分) 最短路最大点权+求相同cost最短路的数量
    PAT-1001 A+B Format (20 分) 注意零的特例
    利用requests和BeautifulSoup爬取菜鸟教程的代码与图片并保存为markdown格式
    菜鸟教程上的设计模式代码合集
    用python将项目中的所有代码(或txt)合并在一个文件中
    POJ 2485 Prim 找最长的边
  • 原文地址:https://www.cnblogs.com/sparkleDai/p/7605069.html
Copyright © 2011-2022 走看看