private void DoGUISwitch() {
// cruisin for a bruisin' through exception city
object1.Visible = true;
object2.Visible = false;
}
变成:
private void DoGUISwitch() {
if (object1.InvokeRequired) {
object1.Invoke(new MethodInvoker(() => { DoGUISwitch(); }));
} else {
object1.Visible = true;
object2.Visible = false;
}
}
这在C#中是一个笨拙的模式,无论是记忆还是键入都是如此。有没有人想出了某种捷径或构造,可以在一定程度上自动化这一点?如果有一种方法可以将函数附加到执行此检查的对象上,而不必执行所有这些额外的工作,比如object1.InvokeIfNecessary.visible = true
类型的快捷方式,那就太酷了。
以前的answers已经讨论了每次只调用Invoke()的不切实际,即使这样,Invoke()语法也是低效的,而且处理起来仍然很笨拙。
那么,有没有人想出什么捷径呢?
发布于 2010-03-03 07:37:10
你可以写一个扩展方法:
public static void InvokeIfRequired(this Control c, Action<Control> action)
{
if(c.InvokeRequired)
{
c.Invoke(new Action(() => action(c)));
}
else
{
action(c);
}
}
并像这样使用它:
object1.InvokeIfRequired(c => { c.Visible = true; });
编辑:正如Simpzon在评论中指出的那样,你也可以将签名更改为:
public static void InvokeIfRequired<T>(this T c, Action<T> action)
where T : Control
发布于 2010-03-03 08:05:29
下面是我在所有代码中使用的表单。
private void DoGUISwitch()
{
Invoke( ( MethodInvoker ) delegate {
object1.Visible = true;
object2.Visible = false;
});
}
我是基于博客条目here来实现的。我没有让这种方法让我失败,所以我认为没有理由通过检查InvokeRequired
属性来使我的代码复杂化。
希望这能有所帮助。
发布于 2011-02-15 21:42:56
创建一个ThreadSafeInvoke.snippet文件,然后只需选择update语句,右击并选择‘环绕...’。或Ctrl-K+S:
<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippet Format="1.0.0" xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<Header>
<Title>ThreadsafeInvoke</Title>
<Shortcut></Shortcut>
<Description>Wraps code in an anonymous method passed to Invoke for Thread safety.</Description>
<SnippetTypes>
<SnippetType>SurroundsWith</SnippetType>
</SnippetTypes>
</Header>
<Snippet>
<Code Language="CSharp">
<![CDATA[
Invoke( (MethodInvoker) delegate
{
$selected$
});
]]>
</Code>
</Snippet>
</CodeSnippet>
https://stackoverflow.com/questions/2367718
复制相似问题