如何编写PostSharp Invoke方面以简化跨线程控制更新

当我想跨线程更新控件时,我通常最终会这样做:

this.Invoke((MethodInvoker)delegate { SomeProcedure(); }); 

建议的方法实际上就是调用你想要更新的特定控件的调用者,但99%的时候表单(即我的例子中的’this’)和控件都将在同一个控件上创建线程所以我真的很喜欢这样做,为了简单起见。

我在想,如果我只是将一个PostSharp方面置于SomeProcedure之上,将它包含在我的那个混乱的声明中,这将是很好的。

然后去…(哦是啊,第一个可用的答案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]装饰。 如果它已经在主线程上,它只运行该方法。 如果不是,它将异步提升方法调用作为主线程的委托。

编辑:我只是想(你已经晚了)你要求使用特定的调用方法来处理你正在使用的目标控件。 假设您在控件的子类上装饰实例方法:

 [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(); } }