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



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

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]装饰即可。 如果它已经在主线程上,它只是运行该方法。 如果不是,它将方法调用异步提升为主线程的委托。

编辑:我刚刚发现(已经晚了)您要求对您正在使用的目标控件使用特定的调用方法。 假设您在控件的子类上修饰实例方法:

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

最新更新