• Winform之UI后台线程


    多线程,一个古老的话题,今天我来聊下最基本的线程,UI线程和后台线程。

    在后台线程中直接操作UI控件会出现异常(线程间操作无效:从不是创建控件“XX”的线程访问它)。怎么解决这个问题那?关键点在代理和InvokeRequired属性,Winform的UI(窗口)代码如下:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;

    using LandpyLibrary;
    using LandpyCommon;

    namespace LandpyWindowsForm
    {
        
    public partial class MainForm : Form, IFormWorkThread
        {
            
    public MainForm()
            {
                InitializeComponent();
                cdObj 
    = SetTime;
            }

            
    private delegate void ControlDelegate(string time);
            
    private WorkThread wtObj;
            ControlDelegate cdObj;

            
    private void SetTime(string time)
            {
                lblTime.Text 
    = time;
            }

            
    public void ShowTime(string time)
            {
                
    if (lblTime.InvokeRequired)
                {
                    Invoke(cdObj, time);
                }
                
    else
                {
                    SetTime(time);
                }
            }

            
    private void btnStart_Click(object sender, EventArgs e)
            {
                wtObj 
    = new WorkThread(this);
                wtObj.StartShowTime();
            }

            
    private void btnEnd_Click(object sender, EventArgs e)
            {
                
    if (wtObj != null)
                {
                    wtObj.EndShowTime();
                }
            }

            
    private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
            {
                
    if (wtObj != null)
                {
                    wtObj.EndShowTime();
                }
            }
        }
    }

    为了能在后台线程中操作UI线程,我们的MainForm继承了公共接口IFormWorkThread,接口定义如下:

    using System;
    using System.Collections.Generic;
    using System.Text;

    namespace LandpyCommon
    {
        public interface IFormWorkThread
        {
            void ShowTime(string time);
        }
    }

    该接口放在一个独立的Dll中,UI线程和后台线程也均处于不同的程序集中,它们均引用了该接口的Dll。

    后台线程类如下:

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Threading;

    using LandpyCommon;

    namespace LandpyLibrary
    {
        
    public class WorkThread
        {
            
    private IFormWorkThread _formWorkThread;
            
    private Thread thread;

            
    public WorkThread(IFormWorkThread formWorkThread)
            {
                _formWorkThread 
    = formWorkThread;
            }

            
    public void Deal()
            {
                
    while (true)
                {
                    Thread.Sleep(
    1000);
                    _formWorkThread.ShowTime(DateTime.Now.ToString());
                }
            }

            
    public void StartShowTime()
            {
                thread 
    = new Thread(new ThreadStart(Deal));
                thread.Name 
    = "TimeThread";
                thread.Start();
            }

            
    public void EndShowTime()
            {
                thread.Abort();
            }
        }
    }

    其实报异常是因为多线程操作UI控件是非安全的,MS提供了解决方案,关键代码如下:

            public MainForm()
            {
                InitializeComponent();
                cdObj = SetTime;
            }

            private delegate void ControlDelegate(string time);
            ControlDelegate cdObj;

            private void SetTime(string time)
            {
                lblTime.Text = time;
            }

            public void ShowTime(string time)
            {
                if (lblTime.InvokeRequired)
                {
                    Invoke(cdObj, time);
                }
                else
                {
                    SetTime(time);
                }
            }

    通过代理和InvokeRequired属性解决了这个问题。

    敬告

    作者:pangxiaoliang
    出处:http://www.cnblogs.com/pangxiaoliang
    本文版权归pangxiaoliang和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,谢谢合作。
  • 相关阅读:
    oracle安装过程中遇到的问题
    HttpContext.Current 的缺陷
    oracle 复杂语句
    .net 中 ref out params的区别
    查看修改mysql编码方式[转载]
    Oracle 中的dual是什么东西
    KindEditor问题汇总【不定时更新】
    java中import、package作用和用法
    [笔记]: 哈弗曼树(最优二叉树) 标签: 二叉树 2017-05-17 16:38 34人阅读 评论(0) 收
    [noip 2004普及组] FBI树 标签: 二叉树递归 2017-05-17 14:29 40人阅读 评论(0)
  • 原文地址:https://www.cnblogs.com/pangxiaoliang/p/1512729.html
Copyright © 2020-2023  润新知