这是我的代码:

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之前执行操作,并且我丢失了一些“消息”。

如何避免这种情况?

最佳答案

如果我正确理解了您的要求,那么可以使用try/catch块的第三部分-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时才运行它吗?例如,如果您通过简单的按钮单击而不是后台线程运行它,则InvokeRequired将是false,并且代码将永远不会执行。

如果您想知道是否最终将始终被调用,那么这个特定问题已经被问过很多次了。例如,参见If I return out of a try/finally block in C# does the code in the finally always run?。那有一些有趣的反例。

您可以考虑的另一种选择是简单地对您的异常进行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);

    }

}

10-06 08:43