跨线程UI组件调用
这是处理跨线程操作的适当方法吗?
我应该使用新的属性名称,例如“EditValueThreadSafe”而不是覆盖“EditValue”吗? 我不认为EditValue的实现发生了变化,因为无论如何调用基本属性。
namespace MyApplication.Components { using System.Windows.Forms; /// /// Thread-safe implementation of the DevExpress.XtraEditors.ComboBoxEdit class. /// public class ComboBoxEditThreadSafe : DevExpress.XtraEditors.ComboBoxEdit { /// /// Gets or sets the edit value. /// /// The edit value. public override object EditValue { get { return base.EditValue; } set { if (this.InvokeRequired) { this.Invoke(new MethodInvoker(delegate { this.SetEditValue(value); })); } else { this.SetEditValue(value); } } } /// /// Sets the edit value. /// /// The value. private void SetEditValue(object value) { base.EditValue = value; } } }
您还可以委托另一个执行该工作的方法,并且在该方法中,如果在错误的线程上(BeginInvoke返回true),则再次调用相同的方法。 这样做可以消除重复代码的需要。
public class ComboBoxEditThreadSafe : DevExpress.XtraEditors.ComboBoxEdit { public override object EditValue { get { return base.EditValue; } set { SetValue(value); } } private void delegate SetValueDlg(object valeu); private void SetValue(object value) { if (this.InvokeRequired) this.BeginInvoke( (SetValueDlg)SetValue, // calls itself, but on correct thread new object[] { value }); else base.editValue = value; } }
您还可以使用Action()generics类来消除创建显式委托类的需要…
public class ComboBoxEditThreadSafe : DevExpress.XtraEditors.ComboBoxEdit { public override object EditValue { get { return base.EditValue; } set { SetValue(value); } } private void SetValue(object value) { if (this.InvokeRequired) this.BeginInvoke( new Action
}
这是线程安全的,是的,但要警惕覆盖一个属性并从根本上改变行为。 更改实现很好,但此属性现在表现得非常不同,消除了特定exception的可能性,但引入了可能的死锁或阻塞条件,这会影响调用代码。
所以,是的,这是正确使用InvokeRequired和Invoke,但我建议创建一个单独的,特定于目的和线程安全的属性,这样做是通告的。
我的UI方法最终看起来像这样:
public void setStatusLabelText(String s) { if (footerStatusLabel.InvokeRequired) { StringUpdateInvokeDelegate callback = new StringUpdateInvokeDelegate(setStatusLabelText); this.Invoke(callback, new object[] { s }); } else { this.footerStatusLabel.Text = s; } }
(这对于.net来说可能已经过时了 – 但重点是你可以在这个方法中进行操作,如果你已经在正确的线程上了 – 让它稍微不那么烦人的阅读,但与Java相比仍然很烦人, IMO)。
我会在这里注2美分。 对InvokeRequired / BeginInvoke / Invoke的实际调用并不完全是线程安全的。 (请参阅在跨线程WinForm事件处理中避免Invoke / BeginInvoke的问题? )我建议找一些方法在单个位置隔离对这些调用,实用程序api,扩展方法等。 在上面的文章中,有一个包含委托以提供线程安全行为的类的完整代码。
上述就是C#学习教程:跨线程UI组件调用分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/943317.html