基于接口和队列的线程操作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了:)
专注于可靠、高性能的Socket TCP通讯组件
作者: Leo_wl
出处: http://www.cnblogs.com/Leo_wl/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
版权信息查看更多关于基于接口和队列的线程操作UI方式的详细内容...