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

调用任何交叉线程代码的最佳方法?

如何解决《调用任何交叉线程代码的最佳方法?》经验,为你挑选了3个好方法。

我知道之前已经问过这个问题,但我正在寻找一种方法:

    简化安全交叉线程代码的创建.

    在任何情况下重用此代码(没有Windows窗体引用).

这是我到目前为止,但我想删除Windows窗体引用.有任何想法吗?

public delegate void SafeInvokeDelegate(System.Action action);
public class SafeInvoke
{
    private readonly System.Windows.Forms.Control _threadControl;

    public SafeInvoke()
    {
        _threadControl = new System.Windows.Forms.Control();
    }

    public void Invoke(System.Action action)
    {
        if (_threadControl.InvokeRequired)
            _threadControl.Invoke(new SafeInvokeDelegate(Invoke), new object[] {action});
        else if (action != null) action();
    }
}

上面的类可能会这样使用:

SafeInvoke _safeInvoker = new SafeInvoke();
void SafeClearItems()
{
    _safeInvoker.Invoke(delegate
        {
            listView1.Items.Clear();
        });
}

我如何删除SafeInvoke类中的System.Windows.Forms.Control但保持相同的功能?



1> Samuel..:

您还可以使用扩展方法和lambdas来使代码更清晰.

using System.ComponentModel;
public static class ISynchronizeInvokeExtensions
{
  public static void InvokeEx(this T @this, Action action) where T : ISynchronizeInvoke
  {
    if (@this.InvokeRequired)
    {
      @this.Invoke(action, new object[] { @this });
    }
    else
    {
      action(@this);
    }
  }
}

所以现在您可以InvokeEx在任何ISynchronizeInvoke上使用,并且能够访问实现类的属性和字段.

this.InvokeEx(f => f.listView1.Items.Clear());


为什么不简单地`listView1.InvokeEx(lv => lv.Items.Clear());`?

2> Jon Skeet..:

ISynchronizeInvoke而不是Control.这是Control实现的接口Invoke/BeginInvoke/EndInvoke/InvokeRequired.

另一种方法是使用SynchronizationContext.Current- BackgroundWorker我相信这是什么用途.



3> 小智..:

如今,Invoke很容易.
例如,假设我们要调用Label(lblVal)来获取txtVal的值

lblVal.Invoke((MethodInvoker)delegate{lblVal.Text = txtVal.Text;});

......就这么简单:D

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