我知道之前已经问过这个问题,但我正在寻找一种方法:
简化安全交叉线程代码的创建.
在任何情况下重用此代码(没有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但保持相同的功能?
您还可以使用扩展方法和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());
用ISynchronizeInvoke
而不是Control
.这是Control
实现的接口Invoke/BeginInvoke/EndInvoke/InvokeRequired
.
另一种方法是使用SynchronizationContext.Current
- BackgroundWorker
我相信这是什么用途.
如今,Invoke很容易.
例如,假设我们要调用Label(lblVal)来获取txtVal的值
lblVal.Invoke((MethodInvoker)delegate{lblVal.Text = txtVal.Text;});
......就这么简单:D