1

我不太擅长代表,我不明白幕后发生的事情。从cross thread operation不同线程访问 UI 项目时出现错误。

我想做的是在一个Utility类中编写一个通用函数,以便我可以将任何方法/代码块传递给该函数。我可以通过多种方式做到这一点,例如:

  1. delegate void UpdateGui(Control c, Action action);
    public static void Do(Control c, Action action)
    {
        try
        {
            if (c.InvokeRequired)
            {
                UpdateGui updaterdelegate = new UpdateGui(Do);
                c.TopLevelControl.Invoke(updaterdelegate, new object[] { c, action });
            }
            else
                action();
        }
        catch (Exception ex)
        {
            //throw ex;
        }
    }
    
  2. public static void Do(Control c, Action action)
    {
        try
        {
            if (c.InvokeRequired) 
            {
                c.TopLevelControl.Invoke((Action)delegate { Do(c, action); });
            }
            else
                action();
        }
        catch (Exception ex)
        {
            //throw ex;
        }
    }
    
  3. public static void Do(Control c, Action action)
    {
        try
        {
            if (c.InvokeRequired)
            {
                c.TopLevelControl.Invoke(action);
            }
            else
                action();
        }
        catch (Exception ex)
        {
            //throw ex;
        }
    }
    
  4. public static void Do(Control c, Action action)
    {
        try
        {
            if (c.InvokeRequired) 
            {
                c.TopLevelControl.Invoke(new MethodInvoker(() => action()));
            }
            else
                action();
        }
        catch (Exception ex)
        {
            //throw ex;
        }
    }
    
  5. public static void Do(Control c, Action action)
    {
        try
        {
            if (c.InvokeRequired) 
            {
                c.TopLevelControl.Invoke(new MethodInvoker(delegate { action(); }));
            }
            else
                action();
        }
        catch (Exception ex)
        {
            //throw ex;
        }
    }
    
  6. public static void Do(Control c, Action action)
    {
        try
        {
            if (c.InvokeRequired) 
            {
                c.TopLevelControl.Invoke((MethodInvoker)delegate { action(); });
            }
            else
                action();
        }
        catch (Exception ex)
        {
            //throw ex;
        }
    }
    

我相信方法 1 和 2 基本相同,方法 4、5 和 6 也是如此。我的问题是:

  1. 方法 (1 & 2)、3 和 (4, 5 & 6) 之间有什么区别?我的意思是在什么情况下一个人处理/照顾另一个人不处理?

  2. 什么是避免cross thread operation错误的正确方法,从某种意义上说,它处理所有情况,最好是简洁易读?

4

1 回答 1

3

您上面的“第三种”方法(仅使用Action)更简单,更有效。您使用的其他方法delegate创建一个单独的方法(通过delegate关键字的匿名方法),然后调用您的原始委托(action参数),这是不必要的。

第3个选项只是直接使用Action传入的,比较简单。

第一个选项是类似的,但在这种情况下,您传递的是不必要的值(the Control)加上必须定义一个自定义委托(尽管您可以使用它Action<Control,Action>)。由于没有使用控件,因此没有理由增加这种复杂性。

附带说明 - 当您在异常处理程序中重新抛出时,最好只使用throw;(而不是throw ex;),因为这将正确保留堆栈跟踪:

catch (Exception ex)
{
    // Do whatever, ie: logging
    throw;
}

如果您不打算登录,而只是打算重新抛出,则可以完全省略try/ catch

于 2012-10-15T18:45:09.493 回答