我不是很擅长代表,我也不知道幕后发生了什么。从其他线程访问UI项时,我收到cross thread operation
错误。
我想要做的是在Utility
类中编写泛型函数,以便将任何方法/代码块传递给函数。我可以通过以下方式做到:
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;
}
}
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;
}
}
public static void Do(Control c, Action action)
{
try
{
if (c.InvokeRequired)
{
c.TopLevelControl.Invoke(action);
}
else
action();
}
catch (Exception ex)
{
//throw ex;
}
}
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;
}
}
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;
}
}
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& 2),3和(4,5& 6)之间有什么区别?我的意思是处理/照顾其他人不会的情况是什么?
什么是避免cross thread operation
错误的正确方法,从某种意义上说它处理所有情况,最好简洁易读?
答案 0 :(得分:3)
上面的“第三种”方法(仅使用Action
)更简单,更有效。您使用delegate
的其他方法会创建一个单独的方法(通过delegate
关键字的匿名方法),然后调用原始委托(action
参数),这是不必要的。
第三个选项只是直接使用传入的Action
,这更简单。
第一个选项是类似的,但在这种情况下,您传递的是不必要的值(Control
)以及必须定义自定义委托(尽管您可以使用Action<Control,Action>
代替)。由于没有使用Control,因此没有理由增加这种复杂性。
旁注 - 当您在异常处理程序中重新抛出时,最好只使用throw;
(而不是throw ex;
),因为这将正确保留堆栈跟踪:
catch (Exception ex)
{
// Do whatever, ie: logging
throw;
}
如果您不打算登录,并且只是打算重新计划,则可以完全忽略try
/ catch
。