我有一个文本框有一个相当大的_TextChanged事件处理程序.在正常打字条件下,性能是好的,但是当用户执行长时间的连续动作时,如保持退格按钮一次性删除大量文本,可能会明显滞后.
例如,事件花了0.2秒才能完成,但用户每0.1秒执行一次删除.因此,它不能赶上,需要处理积压的事件,导致UI滞后.
但是,事件不需要为这些中间状态运行,因为它只关心最终结果.有什么办法让事件处理程序知道它只能处理最新的事件,并忽略所有以前的陈旧变化?
解决方法
我根据经验发现了几个这个问题,这个解决方案简单而整洁.它在
Windows窗体中工作,但可以轻松转换为WPF.
怎么运行的:
当TypeAssistant的对象被通知发生文本更改时,它将运行一个计时器.然后等待MilliSeconds之后,计时器会引发空闲事件.通过处理这个事件你可以做你的工作.如果同时发生另一个文本更改,定时器将重置.
public class TypeAssistant { public event EventHandler Idled = delegate { }; public int WaitingMilliSeconds { get; set; } System.Threading.Timer waitingTimer; public TypeAssistant(int waitingMilliSeconds = 600) { WaitingMilliSeconds = waitingMilliSeconds; waitingTimer = new Timer(p => { Idled(this,EventArgs.Empty); }); } public void TextChanged() { waitingTimer.Change(WaitingMilliSeconds,System.Threading.Timeout.Infinite); } }
用法:
public partial class Form1 : Form { TypeAssistant assistant; public Form1() { InitializeComponent(); assitant = new TypeAssistant(); assitant.Idled += assitant_Idled; } void assistant_Idled(object sender,EventArgs e) { this.Invoke( new MethodInvoker(() => { // do your job here })); } private void yourFastReactingTextBox_TextChanged(object sender,EventArgs e) { assistant.TextChanged(); } }
优点:
>简单!
>在WPF和Windows窗体中工作
>使用.NET Framework 3.5
缺点:
>再运行一个线程>需要调用而不是直接操纵表单