インクリメンタルサーチ系を作るとき、だいたいTextChangedにそのまま処理をくっつけてしまうのだけど、量が多いとカクついてしまうので、TextChangedが連続していた場合Timerで遅延処理をつけたほうがいい。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
using System; using System.Windows.Forms; namespace WindowsFormsApp2 { public partial class Form1 : Form { public Form1() { InitializeComponent(); this.Text = "0"; var delayExecute = new DelayExecute2(); delayExecute.Execute += (s, e) => CutTree(); textBox1.TextChanged += (s, e) => { delayExecute.ReserveExecute(); }; button1.Click += (s, e) => { this.Text = "0"; textBox1.Text = ""; }; } private void CutTree() { int i = Convert.ToInt32(this.Text); Invoke(new Action(() => { this.Text = (i + 1).ToString(); })); } } /* Timer System.Windows.Forms.Timer:WindowsForm向け。同一スレッド System.Threading.Timer:軽量、別スレッド System.Timers.Timer:高精度、別スレッド */ class DelayExecute { public event EventHandler Execute; public int DelayTime = 500; System.Threading.Timer Timer; public DelayExecute() { Timer = new System.Threading.Timer(x => { Execute(this, EventArgs.Empty); }); } public void ReserveExecute() { Timer.Change(DelayTime, System.Threading.Timeout.Infinite); //Change(遅延時間,間隔)Timeout.Infiniteで無効化 } } class DelayExecute2 { public event EventHandler Execute; System.Timers.Timer Timer; public DelayExecute2() { Timer = new System.Timers.Timer(); Timer.AutoReset = false; Timer.Elapsed += (s, e) => Execute(this, EventArgs.Empty); // Interval後にElapsedの初回起動 Timer.Interval = 500; } public void ReserveExecute() { Timer.Start(); Timer.Interval = 500; } } } |