【问题标题】:Alternative to calling Application.DoEvents() in a loop needed需要在循环中调用 Application.DoEvents() 的替代方法
【发布时间】:2014-03-27 21:56:41
【问题描述】:

下面的 c# 代码绝不是理想的,我真的只是在寻找关于如何最好地重构它并使代码更安全的建议和建议。

基本上有一个类变量存储安全检查阶段的值(初始化为0)。当按下我的应用程序中的按钮时,将运行以下代码以检查用户是否有权访问其帐户屏幕。根据方法参数,调用适当的处理程序方法,该方法向用户显示 PIN 输入用户控件(此用户控件是显示为全屏和最顶部的自定义控件)。当处理程序代码运行时,下面显示的代码在 do while 循环中调用 Application.DoEvents,以在用户输入其 PIN 时保持一切响应。如果 do while 循环不存在,则在我们有机会验证用户 PIN 是否正确之前,用户尝试访问的屏幕将出现在 PIN 输入屏幕的顶部。当 PIN 输入通过时,安全检查阶段变量设置为 1,允许显示帐户屏幕。

            try
            {
                this.Cursor = Cursors.WaitCursor;

                Application.DoEvents();

                SecurityCheckStage = 0;

                Security             = new tskSecurity(true);
                Security.TaskUpdate += new TaskUpdateHandler(_handler);

                TaskManager.AddTask(Security, true);

                this.Cursor = Cursors.Default;

                // Wait until security check has passed before showing account screen
                do
                {
                    Application.DoEvents();
                    System.Threading.Thread.Sleep(100);
                }
                while (SecurityCheckStage == 0);

                if (SecurityCheckStage == 1) ShowAccountScreen();

                return false;
            }
            catch
            {
                throw;
            }
            finally
            {
                this.Cursor = Cursors.Default;
            }

我知道在循环中调用Application.DoEvents() 不是一个好习惯,所以我真的想重新编写这段代码以使其更好。

任何帮助将不胜感激。请记住,该问题的解决方案必须适用于 .NET 3.5 Framework。

【问题讨论】:

  • 只需使用 ShowDialog 和计时器。
  • 我已经改写了我的问题,以表明 PIN 条目实际上是自定义用户控件而不是表单,因此它没有“ShowDialog”方法。我需要保持不变,因为这是我正在处理的一个大型遗留项目。
  • 如果您无法重构代码以将该用户控件放入表单中以便您可以正确使用 ShowDialog(),那么您将面临一个非常非常更大的问题。
  • 如果它确实是遗留问题并且您无法更改:将 DoEvents() 留在原处并继续。
  • 感谢大家的意见和建议。

标签: c# multithreading doevents


【解决方案1】:

使用System.Windows.Forms.Timer... 例如:

//...

    timer.Tick += TimerEventProcessor;
    timer.Start();
//..
private void TimerEventProcessor(Object sender, EventArgs myEventArgs)
{
    if (SecurityCheckStage == 1)
    {
        var timer = (Timer) sender;
        timer.Stop();
        ShowAccountScreen();
    }
}

【讨论】:

  • 谢谢彼得,我已经改用这种方法了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-31
  • 1970-01-01
  • 1970-01-01
  • 2017-01-01
  • 2012-04-13
  • 2023-02-05
相关资源
最近更新 更多