​​基于接口和队列的线程操作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了