当前位置:  开发笔记 > 编程语言 > 正文

将线程安全访问方法写入Windows窗体控件的最短方法

如何解决《将线程安全访问方法写入Windows窗体控件的最短方法》经验,为你挑选了3个好方法。

在这篇文章中:

http://msdn.microsoft.com/en-us/library/ms171728(VS.80).aspx

作者使用以下方法对Windows窗体控件进行线程安全调用:

private void SetText(string text)
{
    // InvokeRequired required compares the thread ID of the
    // calling thread to the thread ID of the creating thread.
    // If these threads are different, it returns true.
    if (this.textBox1.InvokeRequired)
    {    
        SetTextCallback d = new SetTextCallback(SetText);
        this.Invoke(d, new object[] { text });
    }
    else
    {
        this.textBox1.Text = text;
    }
}

是否有更短的方法来完成同样的事情?



1> casperOne..:

C#3.0以及之后:

扩展方法通常是要走的路,因为您总是希望在ISynchronizeInvoke接口实现上执行操作,这是一个很好的设计选择.

您还可以利用匿名方法(闭包)来解释您不知道要传递给扩展方法的参数的事实; 关闭将捕获所需的一切状态.

// Extension method.
static void SynchronizedInvoke(this ISynchronizeInvoke sync, Action action)
{
    // If the invoke is not required, then invoke here and get out.
    if (!sync.InvokeRequired)
    {
        // Execute action.
        action();

        // Get out.
        return;
    }

    // Marshal to the required context.
    sync.Invoke(action, new object[] { });
}

然后你会这样称呼它:

private void SetText(string text)
{
    textBox1.SynchronizedInvoke(() => textBox1.Text = text);
}

这里,闭包在text参数上,该状态被捕获并作为传递给扩展方法的Action委托的一部分传递.

在C#3.0之前:

你没有lambda表达式的奢侈,但你仍然可以概括代码.它几乎相同,但不是扩展方法:

static void SynchronizedInvoke(ISynchronizeInvoke sync, Action action)
{
    // If the invoke is not required, then invoke here and get out.
    if (!sync.InvokeRequired)
    {
        // Execute action.
        action();

        // Get out.
        return;
    }

    // Marshal to the required context.
    sync.Invoke(action, new object[] { });
}

然后用匿名方法语法调用它:

private void SetText(string text)
{
    SynchronizedInvoke(textBox1, delegate() { textBox1.Text = text; });
}



2> alex2k8..:

1)使用匿名代表

private void SetText(string text)
{
    if (this.InvokeRequired)
    {    
        Invoke(new MethodInvoker(delegate() {
            SetText(text);
        }));
    }
    else
    {
        this.textBox1.Text = text;
    }
}

2)AOP方法

[RunInUIThread]
private void SetText(string text)
{
    this.textBox1.Text = text;
}

http://weblogs.asp.net/rosherove/archive/2007/05.aspx?PageIndex=2

3)使用lambda表达式(由其他人概述).



3> Quintin Robi..:

编辑:我应该提到我不会认为这是最佳做法

如果使用的是3.5,则可以使扩展方法达到以下效果:

public static void SafeInvoke(this Control control, Action handler) {
    if (control.InvokeRequired) {
        control.Invoke(handler);
    }
    else {
        handler();
    }
}

这基本上是从:这里

然后像这样使用它:

textBox1.SafeInvoke(() => .... );

当然,请修改扩展名等以供您使用。

推荐阅读
吻过彩虹的脸_378
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有