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

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

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

    public interface IInvokeItem
        {
            void Execute();
        }

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

    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);
            }
        }

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

    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的工作。

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

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

    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了:)

    访问Beetlex的Github
  • 相关阅读:
    131. Palindrome Partitioning
    130. Surrounded Regions
    129. Sum Root to Leaf Numbers
    128. Longest Consecutive Sequence
    125. Valid Palindrome
    124. Binary Tree Maximum Path Sum
    122. Best Time to Buy and Sell Stock II
    121. Best Time to Buy and Sell Stock
    120. Triangle
    119. Pascal's Triangle II
  • 原文地址:https://www.cnblogs.com/smark/p/2624942.html
Copyright © 2011-2022 走看看