• 利用数据绑定(DataBinding)简化多线程数据展示


    经常做WinForm开发的人可能会遇到这样一种情况,WinForm程序后台有许多线程在执行任务,前台界面需要适时或定时显示后台任务执行的情况。此类任务界面通常如下:  

    这里存在一个问题是如何在界面上显示后台线程上的状态数据,也就是多线程如何访问控件。

      .NET中的控件并不是线程安全的,因此我们通常是用如下方法在界面上显示后台线程的数据:

    1 private void Test(string val) {
    2     if (txtSuccess.InvokeRequired) {
    3         txtSuccess.Invoke((ShowVal)Test,val);
    4     }
    5     else {
    6         txtSuccess.Text = val;
    7     }
    8 }

    此类方法存在一些问题:

      1,更新代码比较多,且比较晦涩难懂,不易维护;

      2,如果后台状态经常发生变动,则涉及到需要更改的代码可能比较多,如赋值代码,相关委托;

      3,后台线程中除了维护状态外还需显世更新前台界面,造成后台线程代码冗余;

      那么有没有一种比较好的解决方法呢?答案就是数据绑定。通过数据绑定,后台线程只需要维护任务状态而不需要关心这些数据如何显示,而前台界面仅需要不断更新显示数据,而不必关心数据更新来自何方。

      下面以一个简单的例子说明如何利用数据绑定(DataBinding)简化多线程数据展示,假设后台有2个线程在不断处理任务,同时记录了任务执行成功,失败的情况,前台则需要动态显示这些任务的执行状况。任务类简单定义为:

    1 public class TaskEntity {
    2     private int _TaskId = 0;
    3     private int _TaskSuccess = 0;
    4     private int _TaskFail = 0;
    5     public int TaskId { get { return _TaskId; } set { _TaskId = value; } }
    6     public int TaskSuccess { get { return _TaskSuccess; } set { _TaskSuccess = value; } }
    7     public int TaskFail { get { return _TaskFail; } set { _TaskFail = value; } }
    8     public int TaskAll { get { return _TaskSuccess + _TaskFail; } }
    9 }

      然后定义一个全局的数据源用于存放这些任务的引用,同时将该数据源邦定到前台界面上

    01 public List<TaskEntity> dataSource;
    02 private TaskEntity task1;
    03 private TaskEntity task2;
    04 private void InitializeDataSource() {
    05     dataSource = new List<TaskEntity>();
    06     task1 = new TaskEntity();
    07     task1.TaskId = 0;
    08     dataSource.Add(task1);
    09     task2 = new TaskEntity();
    10     task2.TaskId = 1;
    11     dataSource.Add(task2);
    12 }
    13 private void InitializeBinding() {
    14     dataGridView1.DataSource = dataSource;
    15     txtAll.DataBindings.Add(new Binding("Text",task1,"TaskAll"));
    16     txtFail.DataBindings.Add(new Binding("Text", task1, "TaskFail"));
    17     txtSuccess.DataBindings.Add(new Binding("Text", task1, "TaskSuccess"));
    18 }

      然后启动2个后台线程

    01 private Thread thread1;
    02 private Thread thread2;
    03 void btnBS_Click(object sender, EventArgs e) {
    04     workStatus = !workStatus;
    05     if (workStatus) {
    06         thread1 = new Thread(Dowork1);
    07         thread1.Start();
    08  
    09         thread2 = new Thread(Dowork2);
    10         thread2.Start();
    11     }
    12 }

      最后定义数据更新方法

    1 private void UpdateControlValue() {
    2     dataGridView1.Invalidate();
    3     txtAll.DataBindings[0].ReadValue();
    4     txtFail.DataBindings[0].ReadValue();
    5     txtSuccess.DataBindings[0].ReadValue();
    6 }

      做完这些后就可以点击验证,执行结果如下:

      最后通过比对2种方法的实现,执行结果,可以得出,在.NET中利用数据绑定(DataBinding)可以简化多线程数据展示,使得代码的可维护性更高,对于新人也更容易入手。当然,示例中也存在一些问题,如更新不及时,帮定数据源有限制等。但是想比解决的问题,这些代价完全可以承受,并且通过添加简单的同步代码就可以解决。

  • 相关阅读:
    三级菜单的实现方式
    简单登录接口实践
    C++中的set和java的hashset有何区别?
    css 利用文档结构给列表添加样式
    谈谈我对JS中this的理解
    谈谈我对JS原型的理解
    使用node.js,实现简单的JS文件合并小工具
    谈谈我对JS闭包的理解
    谈谈我对JS作用域的理解
    模拟实现 百度翻译 右下方的可折叠的分享按钮列表
  • 原文地址:https://www.cnblogs.com/luluping/p/1809816.html
Copyright © 2020-2023  润新知