当我想跨线程更新控件时,我通常会这样做:
this.Invoke((MethodInvoker)delegate { SomeProcedure(); });
建议的方法实际上是调用要更新的特定控件的调用程序,但 99% 的情况下,表单(即我的示例中的“this”)和控件将在同一台上创建所以为了简单起见,我真的很喜欢这样做。
我在想,如果我能在 SomeProcedure 之上添加一个 PostSharp 方面,将其包装在混乱的声明中,那就太好了。
然后去...(哦,是的,第一个可用答案可获得 100 分奖励:)
我以前没有在 WinForms 上编程过线程访问,但我已经用 PostSharp + Silverlight 完成了。因此,通过一些谷歌搜索,我会尝试一下。但不能保证它有效!
[Serializable]
public class OnGuiThreadAttribute : MethodInterceptionAspect
{
private static Control MainControl;
//or internal visibility if you prefer
public static void RegisterMainControl(Control mainControl)
{
MainControl = mainControl;
}
public override void OnInvoke(MethodInterceptionArgs eventArgs)
{
if (MainControl.InvokeRequired)
MainControl.BeginInvoke(eventArgs.Proceed);
else
eventArgs.Proceed();
}
}
这个想法是在应用程序开始时,使用属性注册您的主/根控件。然后任何你想确保在主线程上运行的方法,只需用[OnGuiThread]
。如果它已经在主线程上,它只会运行该方法。如果不是,它将将该方法调用作为异步委托提升到主线程。
编辑:我刚刚发现(已经晚了)您要求对您正在使用的目标控件使用特定的调用方法。假设你装修instance控件子类的方法:
[Serializable]
public class OnGuiThreadAttribute : MethodInterceptionAspect
{
public override void OnInvoke(MethodInterceptionArgs eventArgs)
{
//you may want to change this line to more gracefully check
//if "Instance" is a Control
Control targetControl = (Control)eventArgs.Instance;
if (targetControl.InvokeRequired)
targetControl.BeginInvoke(eventArgs.Proceed);
else
eventArgs.Proceed();
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)