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



  • 相关阅读:
    堆排序实现
    Unable to convert MySQL date/time value to System.DateTime
    想想那些除了技术之外重要的事情
    js小功能
    01输入框回车触发操作
    javascript闭包
    BQ27510 电量计的校准 的 C语言实现
    嵌入式Linux开发教程:Linux常见命令(上篇)
    技术团队的情绪与效率
    如何有效使用Project(2)——进度计划的执行与监控
  • 原文地址:https://www.cnblogs.com/sparkleDai/p/7605069.html
Copyright © 2011-2022 走看看