【问题标题】:How to write a PostSharp Invoke aspect to simplify cross thread control updates如何编写 PostSharp Invoke 方面以简化跨线程控制更新
【发布时间】:2012-06-25 03:01:36
【问题描述】:

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

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

建议的方法实际上是为您要更新的特定控件调用调用程序,但 99% 的时间表单(即我的示例中的“this”)和控件将被创建在同一个线程上,所以为了简单起见,我真的很喜欢这样做。

我在想,如果我只是在 SomeProcedure 上添加一个 PostSharp 方面会很好,它会为我包装在一个混乱的语句中。

然后去...(哦,是的,第一个可用的答案可获得 100 分奖励 :)

【问题讨论】:

标签: c# winforms postsharp multithreading


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-11
    • 1970-01-01
    • 2012-05-24
    • 2012-05-01
    • 1970-01-01
    相关资源
    最近更新 更多