1

这是我的代码:

foreach (var pathCartella in folderList)
{
    try
    {
        // some operation

        if (txtMonitor.InvokeRequired)
        {
            txtMonitor.BeginInvoke(new MethodInvoker(delegate { txtMonitor.AppendText(pathCartella + Environment.NewLine); }));
        }
    }
    catch (Exception err)
    {
        // some operation
        return;
    }
}

但我注意到,如果我捕捉到一个异常,return可以在所有txtMonitor.InvokeRequired都发送到 UI 之前采取行动,并且我丢失了一些“消息”。

我怎样才能避免这种情况?

4

1 回答 1

4

如果我正确理解您的要求,那么您可以使用 try/catch 块的第三部分 -最后

finally 块对于清理在 try 块中分配的任何资源很有用。不管 try 块如何退出,控制总是传递给 finally 块。该声明采用以下形式:

因此,您的代码将更改为以下形式:

foreach (var pathCartella in folderList)
{
    try
    {
        // some operation


    }
    catch (Exception err)
    {
        // some operation
        return;
    }
    finally
    {
        if (txtMonitor.InvokeRequired)
        {
            txtMonitor.BeginInvoke(new MethodInvoker(delegate { txtMonitor.AppendText(pathCartella + Environment.NewLine); }));
        }
    }
}

几个注意事项 - 你确定你只想运行它InvokeRequiredtrue?例如,如果您通过简单的按钮单击运行它,而不是从后台线程运行它,那么代码InvokeRequiredfalse永远不会执行。

如果你想知道 finally 是否总是会被调用,那么这个问题已经被问过很多次了。请参阅如果我从 C# 中的 try/finally 块返回,finally 中的代码是否总是运行?例如。这有一些有趣的反例。

您可以考虑的另一个选择是简单地throw例外。您可以pathCartella作为错误消息的一部分传递,这样您就知道异常发生在哪条路径上,以及异常是什么。然后,您的呼叫者可以处理此问题。例如:

foreach (var pathCartella in folderList)
{
    try
    {
        // some operation


    }
    catch (Exception err)
    {
        // some operation

        //The original exception becomes the inner exception (so you can get original
        //error and stack trace etc). The new exception message contains the path.
        throw new Exception(
            String.Format("Failed to perform operation on '{0}'", pathCartella), 
            err);

    }

}
于 2013-04-19T07:19:24.727 回答