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
  • 相关阅读:
    PHP的命令行脚本调用
    JAVA使用jar命令制作可执行GUI程序
    PHP的代理模式
    PHP中的__clone()
    PHP使用反射动态加载第三方类
    NAT小记
    JAVA睡眠理发师代码记录
    PHP通过反射获得类源码
    PHP中单引号双引号的区别
    [转载]PHP导出数据库数据字典脚本
  • 原文地址:https://www.cnblogs.com/smark/p/2624942.html
Copyright © 2011-2022 走看看