如何在C#Winform中锁定应用程序GUI

Possible Duplicate:
07000

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

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

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

但是,如果用户再次单击“保存”按钮,则会触发Click事件,当第一次单击返回主代码(保存数据库后)时,捕获的事件将被触发.

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

我怎么能阻止这种行为.

问候,
AKHIL

@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个事件
已被解雇并且控制台窗口正在显示

FirstClick 1:30:22 PM第二次点击1:30:24 PM
FirstClick 1:30:24 PM第二次点击1:30:26 PM
FirstClick 1:30:26 PM第二次点击1:30:28 PM
FirstClick 1:30:28 PM第二次点击1:30:30 PM
FirstClick 1:30:30 PM第二次点击1:30:32 PM

问题是你的程序在将数据保存到数据库时对世界是死的.用户的鼠标单击位于消息队列中,等待UI线程恢复生命.如果执行此操作,则不再禁用该按钮,以便触发Click事件.

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

    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很危险,因为它没有选择处理什么事件.当您的代码仍在运行时,它将很乐意让用户关闭主窗口.

但更好的解决方案是不要让你的UI线程像这样死掉.使用BackgroundWorker在工作线程上执行保存.这也将避免当你的保存需要超过几秒时,Windows提出的丑陋的“无响应”鬼窗口.它现在可能还没有这样做,但是从现在开始dbase成长的那一年.您可以在BGW的RunWorkerCompleted事件处理程序中重新启用该按钮.

https://stackoverflow.com/questions/6423606/how-to-lock-the-application-gui-in-c-sharp-winform

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:如何在C#Winform中锁定应用程序GUI