Don't raise TextChanged while continuous typing

后端 未结 12 1259
闹比i
闹比i 2020-12-14 10:09

I have a textbox that has a fairly hefty _TextChanged event handler. Under normal typing condition the performance is okay, but it can noticeably lag when the u

12条回答
  •  春和景丽
    2020-12-14 10:31

    One easy way is to use async/await on an inner method or delegate:

    private async void textBox1_TextChanged(object sender, EventArgs e) {
        // this inner method checks if user is still typing
        async Task UserKeepsTyping() {
            string txt = textBox1.Text;   // remember text
            await Task.Delay(500);        // wait some
            return txt != textBox1.Text;  // return that text chaged or not
        }
        if (await UserKeepsTyping()) return;
        // user is done typing, do your stuff    
    }
    

    No threading involved here. For C# version older than 7.0, you can declare a delegate:

    Func> UserKeepsTyping = async delegate () {...}
    

    Please note, that this method will not secure you from occasionally processing the same "end reslut" twice. E.g. when user types "ab", and then immediately deletes "b", you might end up processing "a" twice. But these occasions shoud be rare enough. To avoid them, the code could be like this:

    // last processed text
    string lastProcessed;
    private async void textBox1_TextChanged(object sender, EventArgs e) {
        // clear last processed text if user deleted all text
        if (string.IsNullOrEmpty(textBox1.Text)) lastProcessed = null;
        // this inner method checks if user is still typing
        async Task UserKeepsTyping() {
            string txt = textBox1.Text;   // remember text
            await Task.Delay(500);        // wait some
            return txt != textBox1.Text;  // return that text chaged or not
        }
        if (await UserKeepsTyping() || textBox1.Text == lastProcessed) return;
        // save the text you process, and do your stuff
        lastProcessed = textBox1.Text;   
    }
    

提交回复
热议问题