我已经痛苦地意识到,在事件驱动的GUI代码中,人们需要多么频繁地编写以下代码模式
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一样,将函数附加到对象上,无需执行所有这些额外的工作就可以进行检查,那就太棒了。可见= true类型快捷方式。
前面的回答讨论了每次只调用Invoke()的不可行性,即使这样,Invoke()语法也是低效的,而且处理起来仍然很尴尬。
有人找到什么捷径了吗?
我喜欢做的有点不同,如果需要一个动作,我喜欢叫“我自己”,
private void AddRowToListView(ScannerRow row, bool suspend)
{
if (IsFormClosing)
return;
if (this.InvokeRequired)
{
var A = new Action(() => AddRowToListView(row, suspend));
this.Invoke(A);
return;
}
//as of here the Code is thread-safe
这是一个方便的模式,IsFormClosing是一个字段,当我关闭我的表单时,我设置为True,因为可能有一些后台线程仍在运行…
你可以写一个扩展方法:
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
以下是李、奥利弗和斯蒂芬回答的改进版/综合版。
public delegate void InvokeIfRequiredDelegate<T>(T obj)
where T : ISynchronizeInvoke;
public static void InvokeIfRequired<T>(this T obj, InvokeIfRequiredDelegate<T> action)
where T : ISynchronizeInvoke
{
if (obj.InvokeRequired)
{
obj.Invoke(action, new object[] { obj });
}
else
{
action(obj);
}
}
模板允许灵活和无强制转换的代码,这是更可读的,而专用委托提供了效率。
progressBar1.InvokeIfRequired(o =>
{
o.Style = ProgressBarStyle.Marquee;
o.MarqueeAnimationSpeed = 40;
});
我喜欢做的有点不同,如果需要一个动作,我喜欢叫“我自己”,
private void AddRowToListView(ScannerRow row, bool suspend)
{
if (IsFormClosing)
return;
if (this.InvokeRequired)
{
var A = new Action(() => AddRowToListView(row, suspend));
this.Invoke(A);
return;
}
//as of here the Code is thread-safe
这是一个方便的模式,IsFormClosing是一个字段,当我关闭我的表单时,我设置为True,因为可能有一些后台线程仍在运行…