C# 避免跨线程操作错误的最简洁、最恰当的方法?
我不太擅长代表,我不明白在幕后发生了什么。当从不同线程访问UI项时,我得到了C# 避免跨线程操作错误的最简洁、最恰当的方法?,c#,multithreading,C#,Multithreading,我不太擅长代表,我不明白在幕后发生了什么。当从不同线程访问UI项时,我得到了跨线程操作错误 我想做的是在实用工具类中编写一个泛型函数,这样我就可以将任何方法/代码块传递给函数。我可以用很多方法来做,比如: 我相信方法1和2基本上是相同的,4、5和6也是一样的。我的问题是: 方法(1和2)、3和(4、5和6)之间有什么区别?我的意思是,在什么情况下,一方处理/照顾另一方不处理/照顾 避免跨线程操作错误的正确方法是什么?从这个意义上讲,它可以处理所有情况,最好简洁易读 上述“第三种”方法
跨线程操作
错误
我想做的是在实用工具
类中编写一个泛型函数,这样我就可以将任何方法/代码块传递给函数。我可以用很多方法来做,比如:
我相信方法1和2基本上是相同的,4、5和6也是一样的。我的问题是:
跨线程操作
错误的正确方法是什么?从这个意义上讲,它可以处理所有情况,最好简洁易读操作
)更简单、更有效。使用delegate
的其他方法创建一个单独的方法(通过delegate
关键字的匿名方法),然后调用原始委托(操作
参数),这是不必要的
第三个选项直接使用传入的操作
,这更简单
第一个选项与此类似,不过在这种情况下,您将传入不必要的值(控件和必须定义自定义委托的值)(尽管您可以使用操作)。由于没有使用控件,因此没有理由增加这种复杂性
另一方面,当您在异常处理程序中重新调用时,最好只使用throw
(而不是抛出ex;
),因为这将正确保留堆栈跟踪:
catch (Exception ex)
{
// Do whatever, ie: logging
throw;
}
如果你不打算登录,只打算重新浏览,你可以完全省去try
/catch
。我对MethodInvoker
更感到困惑。。它在替代委托
、操作
、()=>
关键字方面做了什么特别的事情?@nawfal这只是另一个委托声明。实际上,这与使用操作
相同。=>
语法是一个lambda表达式,它是用于生成匿名方法的较新语法(类似于委托{}
,但具有更清晰的语法)。
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;
}
}
catch (Exception ex)
{
// Do whatever, ie: logging
throw;
}