簡體   English   中英

C#Windows窗體自定義控件跨線程操作

[英]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,則進行常規調用。

由於thread unsafe call而發生

您應該只在程序中進行線程安全調用

檢查鏈接。

簡短的回答是,您必須使用Invoke。 如果需要詳細信息,請參閱此問題及其公認的答案

順便說一句,僅在某些時間拋出異常的原因歸結為計時。 您當前的比賽條件有時會很幸運,有時卻不會。

順便說一下,這是這種事情的便捷模式。

  1. 重構將表單值設置為自己的私有void方法的所有代碼。
  2. 在此新方法中,調用InvokeRequired 如果返回true,則調用Invoke,並傳遞當前方法,以便遞歸回該方法。 如果返回false,請繼續進行更改。
  3. 從事件處理程序中調用此新方法。

例如:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM