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

3

当我想在不同的线程中更新控件时,通常会按照以下方式进行:

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

建议的方法是调用特定控件的调用程序来更新它,但99%的情况下,窗体(即我的示例中的'this')和控件将在同一线程上创建,所以出于简单起见,我真的很喜欢这种方法。
不过,我认为如果我只需要在SomeProcedure上放置一个PostSharp方面,就可以把它包装在那个混乱的语句中。
开始吧...(哦,是的,第一个可用答案得到100点额外奖励:)

我不完全确定我准确理解您想要的内容,特别是关于您第二段的描述。但是,PostSharp的示例代码是否有所帮助?http://www.sharpcrafters.com/solutions/multithreading - Chris Sinclair
1个回答

8

我以前没有在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();
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接