Bra*_*ore 3 c# multithreading postsharp winforms
当我想跨线程更新控件时,我通常最终会这样做:
this.Invoke((MethodInvoker)delegate { SomeProcedure(); });
Run Code Online (Sandbox Code Playgroud)
建议的方法实际上是调用调用者来获取你想要更新的特定控件,但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();
}
}
Run Code Online (Sandbox Code Playgroud)
这个想法是在你的应用程序的开始,用属性注册你的主/根控件.然后你想要确保的任何方法都在主线程上运行,只需装饰[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();
}
}
Run Code Online (Sandbox Code Playgroud)