用TaskScheduler代替invoke和begininvoke异步更新那界面数据
来源:互联网 发布:战锤全面战争画面优化 编辑:程序博客网 时间:2024/06/14 10:30
在异步编程时,为了更新界面的数据,经常会用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. }
- 用TaskScheduler代替invoke和begininvoke异步更新那界面数据
- C#的Invoke和BeginInvoke、多线程中的界面更新
- c#多线程更新窗口界面之 Invoke和BeginInvoke方法的使用
- Invoke和BeginInvoke
- BeginInvoke和Invoke
- Invoke和BeginInvoke 区别
- Invoke和BeginInvoke
- Invoke 和 BeginInvoke
- Invoke和BeginInvoke
- Invoke() 和BeginInvoke()区别
- Invoke和BeginInvoke
- Invoke 和 BeginInvoke
- Invoke和BeginInvoke
- c# Invoke和BeginInvoke
- Invoke和BeginInvoke
- 【C#】Invoke和BeginInvoke
- C# invoke和beginInvoke
- C# invoke和begininvoke
- Linux系统启动的标准流程
- Android电话和短信拦截器
- Android中时间和日期的显示
- android零碎知识点 字符串转换整数
- Qt学习笔记(2):帮助文档 (Qt助手)
- 用TaskScheduler代替invoke和begininvoke异步更新那界面数据
- javascript 性能分析:响应接口
- Eclipse中,常用的快捷键大全
- 安装LNMP,cacti监控
- AndroidManifest.xml配置文件详解
- 读者写者问题——读者优先,写者优先,公平竞争 解决方法
- svn版本库创建
- Linux内核源码分析方法
- python操作处理Excel文件(转)