[英]C# windows forms custom controls cross-thread operation
我有一個主要的Windows窗體,並且在該窗體中,我具有表示應用程序中不同屏幕的自定義控件。 我想訪問此控件的子控件。 有些東西我沒到這里...有時我會收到此錯誤:
Cross-thread operation not valid: Control 'lblText' accessed from a thread other than the thread it was created on.
但有時候一切正常。 我不完全理解為什么會出現錯誤...可能是外部設備(MEI BillAcceptor)發生了一些事情,該設備具有一個對控件進行更改的事件(在Form1類內部)...所以讓我編寫一個簡單的代碼...
//user control
public partial class Screen2 : UserControl
{
public void changeValue(string txt)
{
lblText.Text = txt;
}
}
並在引發特定事件時從form1調用方法changeValue ...
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
BillAcceptor.SomeBillAcceptorEvent +=
new SomeBillAcceptorEventHandler(changeText);
}
private void changeText(object sender, EventArgs args)
{
_screen2.changeValue("some text");
}
}
因此,最煩人的是,有時一切都可以正常工作。所以我的問題是“我必須在這里使用Invoke嗎?” 或如何通過減少對應用程序的更改來解決此問題...
在您的處理程序中。 做這樣的事情。
if (this.InvokeRequired)
{
Invoke(new MethodInvoker(() =>
{
_screen2.changeValue("some text");
}));
}
else
{
_screen2.changeValue("some text");
}
我猜想該事件是在與主UI線程不同的單獨線程上引發的。
是的,如果有可能從其他線程調用該方法,則需要使用Invoke。
您可以檢查this.InvokeRequired()
,如果為true,則使用invoke,如果為false,則進行常規調用。
簡短的回答是,您必須使用Invoke。 如果需要詳細信息,請參閱此問題及其公認的答案 。
順便說一句,僅在某些時間拋出異常的原因歸結為計時。 您當前的比賽條件有時會很幸運,有時卻不會。
順便說一下,這是這種事情的便捷模式。
InvokeRequired
。 如果返回true,則調用Invoke,並傳遞當前方法,以便遞歸回該方法。 如果返回false,請繼續進行更改。 例如:
private void ChangeScreen2() {
if (this.InvokeRequired) {
this.Invoke(new MethodInvoker(ChangeScreen2));
}
else {
_screen2.changeValue("some text");
}
}
private void changeText(object sender, EventArgs args)
{
ChangeScreen2();
}
這樣的想法是,您將所有修改表單的代碼都隔離到這些方法中,這些方法始終以檢查InvokeRequired
開始,並在需要時始終Invoke
自身。 此模式適用於.NET 1.0及更高版本。 有關更整潔的方法,請參見此問題的公認答案, 該問題適用於.NET 3.0及更高版本。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.