我不太擅长代表,我不明白幕后发生的事情。我得到 cross thread operation
从不同线程访问 UI 项时出错。
我想做的是在 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 也是如此。我的问题是:
cross thread operation
的正确方法是什么?错误,从某种意义上说它处理所有情况,最好是简洁易读? 最佳答案
您上面的“第三种”方法(仅使用 Action
)更简单、更有效。您使用 delegate
的其他方法创建一个单独的方法(通过 delegate
关键字的匿名方法)然后调用您的原始委托(delegate)(action
参数),这是不必要的。
第三个选项直接使用 Action
传入,比较简单。
第一个选项是类似的,但在这种情况下,您传递了不必要的值( Control
)以及必须定义自定义委托(delegate)(尽管您可以使用 Action<Control,Action>
代替)。由于没有使用控件,因此没有理由增加这种复杂性。
附带说明 - 当您在异常处理程序中重新抛出时,最好只使用 throw;
(而不是 throw ex;
),因为这将正确保留堆栈跟踪:
catch (Exception ex)
{
// Do whatever, ie: logging
throw;
}
如果你不打算登录,只是打算重新抛出,你可以省略
try
/catch
完全。
关于c# - 避免跨线程操作错误的最简洁和正确的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12901938/