如何确保InvokeRequired不会中止?

时间:2013-04-19 07:12:56

标签: c# multithreading invokerequired

这是我的代码:

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发送到用户界面之前采取行动,并且我丢失了一些“消息”。

我该如何避免这种情况?

1 个答案:

答案 0 :(得分:4)

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

  

finally块对于清理分配的任何资源非常有用   试块。控制总是传递给finally块   无论try块如何退出。这个陈述需要   以下表格:

所以你的代码会变成某种形式:

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);

    }

}