如何在C#Winform中锁定应用程序GUI [英] how to lock the application GUI in C# Winform

查看:484
本文介绍了如何在C#Winform中锁定应用程序GUI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

可能重复:
如何在后台线程运行时阻止Winforms UI

Possible Duplicate:
How to block Winforms UI while background thread is running

我正在使用C#WinForm应用程序

i am using a C# WinForm application

我在屏幕上有一个保存"按钮,屏幕上的数据已保存到数据库中.

I have a Save button on the screen where the data of the screen is saved to database.

发生什么情况,当用户单击按钮时,应用程序进入数据库并保存数据. 需要一些时间.

what happens, when user clicks to button application goes to database and saves data. it takes some time.

但是,这意味着如果用户再次单击保存"按钮,则会捕获Click事件,并且在第一次Click返回主代码(保存数据库后)时,会触发捕获的事件.

but mean while if user again click on the Save button the Click event get catched and when the first Click return to main code (after saving database) the caught event get fired..

简而言之,当线程从第一个事件返回时,click事件被捕获并触发 (我尝试了启用/禁用按钮的情况.)

In short the click event get caught and fired when the thread returns from the first event ( I tried the scenario of enable/disable the button).

如何停止这种行为.

关于, 阿基尔

@Jalal:我对此代码进行了一些修改,

private readonly object _userActivityLocker = new object();
        private void btnSave_Click(object sender, EventArgs e)
        {
            if (System.Threading.Monitor.TryEnter(_userActivityLocker))
            {
                //note that any sub clicks will be ignored while we are here
                try
                {
                    DateTime dt =  DateTime.Now;
                    Thread.Sleep(2000);
                    Debug.Print("FirstClick {0} Second Click {1}",dt.ToLongTimeString(),  DateTime.Now.ToLongTimeString());
                    //here it is safe to call the save and you can disable the btn
                    Application.DoEvents();
                }
                finally
                {
                    System.Threading.Monitor.Exit(_userActivityLocker);
                    //re-enable the btn if you disable it.
                }
            }
        }

但是当我快速单击按钮时(我进行了5次快速单击检查)有5次单击事件 已被触发,控制台窗口显示

but when i rapidly click on button (i checked with 5 times rapid clicks) 5 click events has been fired and console window is showing

FirstClick 1:30:22 PM SecondClick 1:30:24 PM FirstClick 1:30:24 PM SecondClick 1:30:26 PM FirstClick 1:30:26 PM SecondClick 1:30:28 PM FirstClick 1:30:28 PM SecondClick 1:30:30 PM 第一次点击是1:30:30 PM,第二次点击是1:30:32 PM

FirstClick 1:30:22 PM Second Click 1:30:24 PM FirstClick 1:30:24 PM Second Click 1:30:26 PM FirstClick 1:30:26 PM Second Click 1:30:28 PM FirstClick 1:30:28 PM Second Click 1:30:30 PM FirstClick 1:30:30 PM Second Click 1:30:32 PM

推荐答案

问题是您的程序在将数据保存到数据库时就死了.用户的鼠标单击位于消息队列中,等待您的UI线程恢复运行.启用后,该按钮将不再处于禁用状态,因此会触发Click事件.

The problem is that your program is dead to the world while it is saving the data to the database. The user's mouse click is sitting in the message queue, waiting for your UI thread to come back to life. When it does, the button is no longer disabled so the Click event fires.

您可以通过在重新启用按钮之前清空消息队列来解决此问题,以便在禁用按钮时处理单击:

You can solve it by emptying the message queue before you re-enable the button so the click is processed while the button is disabled:

    private void button1_Click(object sender, EventArgs e) {
        button1.Enabled = false;
        // Save data to database
        //...
        System.Threading.Thread.Sleep(2000);

        Application.DoEvents();   // Empty the message queue
        if (!button1.IsDisposed) button1.Enabled = true;
    }

不要跳过IsDisposed测试,DoEvents很危险,因为它对处理哪些事件没有选择性.当您的代码仍在运行时,它将很乐意让用户关闭主窗口.

Do not skip the IsDisposed test, DoEvents is dangerous because it isn't selective about what events get processed. It will happily let the user close the main window while your code is still running.

但是更好的解决方案是不要让您的UI线程像这样死掉.使用BackgroundWorker在辅助线程上执行保存.这样还可以避免保存时间超过几秒钟时,Windows弹出的丑陋的无响应"幻影窗口.它可能暂时还没有这样做,但是从现在起dbase增长了一年.您可以在BGW的RunWorkerCompleted事件处理程序中重新启用该按钮.

But the better solution is to not let your UI thread go dead like this. Use a BackgroundWorker to perform the save on a worker thread. This will also avoid the ugly "Not Responding" ghost window that Windows puts up when your save takes more than a couple of seconds. It probably doesn't do this yet right now, but it will a year from now when the dbase has grown. You can re-enable the button in the BGW's RunWorkerCompleted event handler.

这篇关于如何在C#Winform中锁定应用程序GUI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆