zoukankan      html  css  js  c++  java
  • 基于接口和队列的线程操作UI方式

    在实际开发应用中,非UI线程操作UI是普遍存在的,在.net下一般是通过Control.Invoke的方法来进行操作,但到处都是Control.Invoke代码维护可是一件麻烦的事情。以下通过接口和队列来规范非UI线程操UI的实现。

       既然要规范处理那接口是个不错的选择,以下定义一个简单的执行接口

    1
    2
    3
    4
    public interface IInvokeItem
        {
            void Execute();
        }

      以下是扩展一个简单的操作类封装

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    class ControlInvoke<CONTROL,DATA> : IInvokeItem
        {
            public ControlInvoke(CONTROL control, DATA data, Action<CONTROL, DATA> action)
            {
                mControl = control;
                mData = data;
                mAction = action;
            }
            private CONTROL mControl;
            private DATA mData;
            private Action<CONTROL, DATA> mAction;
            public void Execute()
            {
                mAction(mControl, mData);
            }
        }

      规则定好了,那接下来要做的事情就是写一个简单的队列处理。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    public class Dispatch
        {
            static Dispatch()
            {
                Instance = new Dispatch();
            }
            public void Add<CONTROL, DATA>(CONTROL control, DATA data, Action<CONTROL, DATA> action)
            {
                ControlInvoke<CONTROL, DATA> item = new ControlInvoke<CONTROL, DATA>(control, data, action);
                Add(item);
            }
            private Queue<IInvokeItem> mQueues = new Queue<IInvokeItem>();
            public static Dispatch Instance
            {
                get;
                set;
            }
            public void Add(IInvokeItem item)
            {
                lock (this)
                {
                    mQueues.Enqueue(item);
                }
            }
            public void Execite()
            {
                lock (this)
                {
                    while (mQueues.Count > 0)
                    {
                        mQueues.Dequeue().Execute();
                    }
                }
            }
        }

      一个简单的调用规则就完成,接下来就是如果在winform下面用了;首先可以在界面定义一个timer,可以指定时间内执行Dispatch的工作。

    1
    2
    3
    4
    private void timer1_Tick(object sender, EventArgs e)
            {
                ThreadInvoke.Dispatch.Instance.Execite();
            }

      当需要在线程中操作UI只需要向ThreadInvoke.Dispatch添加item即可,对于它的执行是完全不用关心的。以下是起一个线程不停地向一个文本框添加一个GUID值

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    private void cmdTest_Click(object sender, EventArgs e)
            {
                System.Threading.ThreadPool.QueueUserWorkItem(OnTest);
            }
            private void OnTest(object state)
            {
                while (true)
                {
                    ThreadInvoke.Dispatch.Instance.Add<RichTextBox, Guid>(
                        richTextBox1, Guid.NewGuid(), (c, d) => {
                            richTextBox1.AppendText(d.ToString("N"));
                            richTextBox1.AppendText("\r\n");
                        });
                    System.Threading.Thread.Sleep(10);
                }
            }

     这样一个不使用Control.Invoke来实现非UI线程操作UI的方法就完成了.至于灵活性来说那就看你如何发挥IInvokeItem了:)

    专注于可靠、高性能的Socket TCP通讯组件
  • 相关阅读:
    BZOJ 1834 Luogu P2604 [ZJOI2010]网络扩容 (最小费用最大流)
    BZOJ 1565 Luogu P2805 [NOI2009]植物大战僵尸 (Tarjan判环、最小割)
    BZOJ 3993 Luogu P3324 [SDOI2015]星际战争 (最大流、二分答案)
    BZOJ 3277 串 & BZOJ 3473 字符串 (广义后缀自动机、时间复杂度分析)
    BZOJ 2806 Luogu P4022 [CTSC2012]Cheat (广义后缀自动机、DP、二分、单调队列)
    Mongodb的聚合和管道
    Mongodb文档查询
    Mongodb的基本操作-数据库 集合 文档的增删改查
    Linux下Mongodb的安装
    mongdb的优势和不足
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2625730.html
Copyright © 2011-2022 走看看