【问题标题】:How to avoid duplicate Cursor.Current statement?如何避免重复 Cursor.Current 语句?
【发布时间】:2012-09-30 08:03:51
【问题描述】:

如果我在处理任务之前打开WaitCursor,然后将其恢复为默认值,我经常会得到这种代码模式:

try {
    Cursor.Current = Cursors.WaitCursor;
    MyProcessingTask();
}
catch (Exception ex) {
    Cursor.Current = Cursors.Default;
    MessageBox.Show(ex.ToString());
}
finally { Cursor.Current = Cursors.Default; }

我需要在catch 块中包含Cursor.Current = Cursors.Default;,以便为MessageBox 提供一个默认光标以供使用。

有没有更好的方法来编写此代码而无需编写两个 Cursor.Current = Cursors.Default; 语句?

【问题讨论】:

  • 您可以删除 finally 块并在 MyProcessingTask(); 调用之后使用 Cursor.Current = Cursors.Default; 语句;否则我认为你会坚持两次。
  • 您是否尝试将try ... finally 语句放入try ... catch 语句的try 块中?
  • @Tim:如果我把它放在MyProcessingTask(); 之后,那么如果MyProcessingTask() 引发异常,我仍然需要将它也放在catch 块中,不是吗?
  • @O.R.Mapper:你能详细说明一下吗?
  • @CJ7:我已将其添加为答案。

标签: c# error-handling cursor try-catch-finally


【解决方案1】:

您可以创建一个一次性类并利用using syntact-sugar,即:

class WaitingCursor : IDisposable
{
    public WaitingCursor()
    {
        Cursor.Current = Cursors.WaitCursor;
    }
    public void Dispose()
    {
        Cursor.Current = Cursors.Default;
    }
}

用法:

try
{
    using (var wcurs = new WaitingCursor())
    {
        MyProcessingTask();
    }
}
catch (Exception ex)
{
    MessageBox.Show(ex.ToString());
}

【讨论】:

  • OP 的问题是将光标改回 before 显示消息框,此解决方案没有这样做。
  • @O.R.Mapper:实际上,当 MessageBox 出现时,它并没有显示等待光标...
  • @O.R.Mapper:但是,使用 try catch 反转使用,您将获得所需的结果(已编辑)。
  • 我没试过;我只是按照 OP 的声明 我需要 Cursor.Current = Cursors.Default;在 catch 块中,以便为 MessageBox 提供一个默认使用的光标。;也许示例代码被意外地过度简化了(例如,非标准消息框)。无论如何,您编辑的解决方案确实有效。
【解决方案2】:

这样的事情怎么样

        Exception exception = null;
        try
        {
            Cursor.Current = Cursors.WaitCursor;
            MyProcessingTask();
        }
        catch (Exception ex)
        {
            exception = ex;
        }

        Cursor.Current = Cursors.Default;
        if (exception!= null)
            MessageBox.Show(exception.ToString());

尽管这似乎是一个可行的解决方案,但我还是建议保留双光标设置,因为我希望所有异常逻辑都在 Catch 块内处理。

【讨论】:

    【解决方案3】:

    您可以在 try/catch 块内嵌套 try/finally 块:

    try {
        try {
            Cursor.Current = Cursors.WaitCursor;
            MyProcessingTask();
        }
        finally { Cursor.Current = Cursors.Default; }
    }
    catch (Exception ex) {
        MessageBox.Show(ex.ToString());
    }
    

    这是否更好可能取决于意见。它减少了一些代码重复,但它(在我看来)并没有“熟悉”的外观。有人可能会在 6 个月内看到这一点,并将其重构回熟悉的 try/catch/finally 结构(并丢失 catch 块中的光标更改)。


    顺便说一句,在这个低级别捕获所有异常的一般模式通常是不受欢迎的。通过仅显示Message“处理”所有可能的异常,您将失去潜在的调试帮助。我通常会建议 a) 你只处理 specific 异常,你的代码实际上有一个明智的策略来处理,b) 让所有其他异常传播到顶级异常处理程序 a)可能会显示一条消息,但 b) 还会记录异常的所有相关部分,包括调用堆栈等。

    吞下异常(如这里)可能意味着应用程序不处于适合继续运行的状态,但会尝试这样做。使最终崩溃(如果发生)更加难以诊断。

    【讨论】:

    • 外部catch块会处理MyProcessingTask()抛出的异常吗?
    • @CJ7:是的,会的。 finally 块没有捕获异常,finally 只是意味着即使控制流跳出当前块也会执行(例如,当return 语句位于@ 的try 块内时) 987654337@声明)。
    • @CJ7 - 是的。发生异常时,它会从引发异常的点向外传播,直到找到匹配的 catch 子句。 catch 子句可以在任何地方——在同一个方法中,或者在调用堆栈中的任何方法中。
    【解决方案4】:

    在现有try ... catch 语句的try 块中嵌套try ... finally 语句,如下所示:

    try {
        Cursor.Current = Cursors.WaitCursor;
        try {
            MyProcessingTask();
        }
        finally {
            Cursor.Current = Cursors.Default;
        }
    }
    catch (Exception ex) {
        MessageBox.Show(ex.ToString());
    }
    

    【讨论】:

      【解决方案5】:

      你可以通过扩展方法来简化这个:

      static void ProcessWithWaitCursor(this Action task)
      {
          try {
              Cursor.Current = Cursors.WaitCursor;
              task();
          }
          catch (Exception ex) {
              Cursor.Current = Cursors.Default;
              MessageBox.Show(ex.ToString());
          }
          finally { Cursor.Current = Cursors.Default; }
      

      }

      然后像这样使用它:

      MyProcessingTask.ProcessWithWaitCursor()
      

      这将消除您想要执行此操作的所有地方的所有重复代码。

      【讨论】:

      • 我相信 OP 正试图消除在 try/catch 中使用相同的两行代码——而这个解决方案没有。
      • 你是对的,但我们的想法是少写,做同样的事情这个答案提供了一种完全不用担心 Cursor 的方法。去掉一条线,他有什么好处?一次是他在术语或代码行中使用这种结构的所有地方。我的解决方案将代码减少到单行。所以我认为这是相关的。
      猜你喜欢
      • 2022-01-09
      • 1970-01-01
      • 2016-06-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-19
      相关资源
      最近更新 更多