在winform页面上防止页面粘滞的方法有很多。 这里介绍的是本人实战过的、高频率更新页面控件的方法。 仅供参考。 其中运用的技术主要有:队列使用、线程使用、委托刷新、用户控件;
首先,封装本地队列服务
使用通用类型t,可以为多个数据类型更新本地页。 主要代码如下:
///summary
//本地队列服务封装
////summary
///typeparam name='T'/typeparam
公共类队列服务器
{
publicreadonlyobject _ lock=new object (;
publicreadonlyeventwaithandle _ wh=newautoresetevent (false;
公共队列队列;
私有只读线程th;
//处理案件
publicdelegatevoideventhandlerprocessing;
publiceventhandlerprocessingprocessing;
//更新队列的剩馀数量
publicdelegatevoidenenthandlerrefresh (int count );
publicenenthandlerrefreshrefreshing;
公共队列服务器(
{
队列=new queuet (;
th=新线程(work )
{
IsBackground=true
(;
}
公共语音开始(
{
th.Start (;
}
公共语音停止(
{
if(th!=null th.ThreadState!=ThreadState.Stopped )
{
th.Abort (;
}
}
publicqueueserver (事件处理程序处理程序)。
{
this.Processing =Processing;
th=新线程(work )
{
IsBackground=true
(;
}
私人语音工作(
{
是wile (真)
{
titem=default(t;
锁定(_ lock ) )。
{
if(queue.count0) )。
{
item=Queue.Dequeue ();
刷新? invoke(queue.count );
if(item==null ) )。
{
返回;
}
}
}
if(item!=空)
{
处理? invoke(item;
}
else
{
_wh.WaitOne (;
}
}
}
公共语音编码(项目) ) ) ) ) ) )。
{
锁定(_ lock ) )。
{
if (! queue.contains(item ) )
{
queue.enqueue(item;
}
}
_wh.Set (;
}
}然后,添加用户控件MyRichTextBox;
主要代码如下,引用队列服务。 使用引用的组件启动队列线程,并将更新事件Refresh注册到队列服务的更新事件中。 为外部提供刷新方法refresh rich text (字符串文本),并将需要刷新的文本添加到队列中。 编译后可以直接在工具栏上使用
[工具箱项tem (true ) ]
publicpartialclassmyrichtextbox :用户控制
{
privatereadonlyqueueserverstringqueueserver=newqueueserverstring (;
公共复盖字符串文本
{
获取
{
return richTextBox1.Text;
}
设定
{
richTextBox1.Text=value;
}
}
公共my richtextbox (
{
初始化组件(;
queueServer.Processing =Refresh;
queueServer.Start (;
}
私密性voidrichtextbox1_ mouseup (对象发送器,鼠标事件) )。
{
if (e.button==mouse buttons.right ) )。
{
上下文菜单1.show (richtextbox 1,newpoint ) e.x,e.Y );
}
}
privatevoidtoolstripmenuitem1_ click (对象发送器,事件发生器) () ) ) ) ) ) ) ) )。
{
richTextBox1.Clear (;
}
publicvoidappendtext (字符串msg ) )。
{
richtextbox1.appendtext(msg;
richtextbox1. selection start=richtextbox1. text.length;
richTextBox1.ScrollToCaret (
}
私有语音(字符串msg )。
{
邀请(if )。
{
invoke(newaction () ) )
{
if(Text.Length2000 ) ) ) )
{
Text=' ';
}
应用文本(# 34; { datetime.now.tostring (mm-ddhh : mm : ss ffff ) } {msg} {Environment.NewLine};
();
}
else
{
if(Text.Length2000 ) ) ) )
{
Text=' ';
}
应用文本(# 34; { datetime.now.tostring (mm-ddhh : mm : ss ffff ) } {msg} {Environment.NewLine};
}
}
publicvoidrefreshrichtext (字符串msg ) )。
{
queueserver.enqueue(msg;
}
其中有一点需要注意
在Refresh方法中,如果主线程访问InvokeRequired=false; 执行以下刷新方法: 如果控件在子线程中使用,则InvokeRequired=true; 这样可以确保在这两种情况下都能正常使用。 否则,ssdxrz会挂起接口。
页面设计
页面设计比较简单,主要实现数据的显示和右键点击的清除。
最后一页调用:
上诉处理后,调用方法也比较简单。 如何将控件拖动到指定的页面并使用控件my richtextbox1. refresh rich text (# 34; 第{info.Number}个,需要时间{st.ElapsedMilliseconds}毫秒'; 可以疯狂地刷新页面。 特别是在监视执行过程和显示处理日志的流水时,非常有用。 也便于与许多页面集成。 当然,使用队列的好处是保证执行顺序的优先关系,方便问题的排除。 否则,它会频繁更新,更容易覆盖数据。
是的,如果对你有帮助的话,你也可以试试。 还有其他更有趣的应对方法。 也可以留言互相交流。