How do I prevent any button click events from queuing until the event handle is finished with the first call

后端 未结 2 1068
时光取名叫无心
时光取名叫无心 2021-01-12 15:20

I want to prevent a button click from queuing. In testing I have a Form, a Button and in the Code-Behind I have the event handler:

    private void button1_C         


        
相关标签:
2条回答
  • 2021-01-12 15:31

    There are various amounts of trouble you'll get into when you hang-up the UI thread like this. This is certainly one of them, nothing pleasant happens when the user wildly bangs on the button to try to get something noticeable to happen. And sure, those clicks won't get lost, they stay stored in the message queue. To activate your Click event handler again when your event handler stops running.

    Pretty important to learn how to use the BackgroundWorker or Task classes to avoid this kind of trouble. Just setting the button's Enabled property is then enough to solve this problem.

    Purging the mouse clicks from the message queue is technically possible. But ugly to do, it requires pinvoke. I'll hesitantly post the alternative, don't assume that this is in general a good strategy. You'll need to read this post to have some insight into why DoEvents() is a dangerous method.

        private void button1_Click(object sender, EventArgs e) {
            button1.Enabled = false;
            button1.Update();
            '' long running code
            ''...
            Application.DoEvents();
            if (!button1.IsDisposed) button1.Enabled = true;
        }
    

    The Update() call ensures that the user gets the feedback he needs to know that banging the button repeatedly isn't going to do anything useful. The DoEvents() call will dispatch all the queued-up mouse clicks, nothing happens with them since the button is still disabled. The IsDisposed test is essential to solve the problem with DoEvents(), it ensures your program won't crash when the user clicked the window's Close button while the code was running.

    Use the HourGlass class in this post to provide more feedback.

    0 讨论(0)
  • 2021-01-12 15:42

    I had a button that on click event was going to run a method. Same issue happent and when the user clicked multiple times the method was triggered multiple times. So I made a boolean and changed it value when the method started.

    private bool IsTaskRunning = false

    private void MyMethod(){
    
    if(IsTaskRunning==false){
    
           IsTaskRunning=true;
    
           //My heavy duty code that takes a long time
    
            IsTaskRunning=false;    //When method is finished
    
       }
     }
    

    So now the method runs only if it's done the last time.

    0 讨论(0)
提交回复
热议问题