簡體   English   中英

如何訪問UI線程上的值?

[英]How can I access values on the UI thread?

我沒有問題通過BeginInvoke調用UI控件上的操作等,但是,這是一個void方法。 我需要從文本框中獲取一個值,以便在不同的線程中使用。

我怎么能做到這一點?

最簡單的解決方案是在閉包中捕獲局部變量。

String text;
textBox.Invoke(() => text = textBox.Text);

編譯器將生成一些類似於chibacity的解決方案的代碼 - 局部變量成為編譯器生成的類的字段。

UPDATE

這不起作用 - lambda表達式不能賦予Delegate 可以使用擴展方法解決此問題。

internal void ExecuteOnOwningThread(this Control control, Action action)
{
    if (control.InvokeRequired)
    {
        control.Invoke(action);
    }
    else
    {
        action();
    }
}

用法如下。

String text;
textBox.ExecuteOnOwningThread(() => text = textBox.Text);

可以將多個語句填充到lambda表達式中。

textBox.ExecuteOnOwningThread(() =>
{
    DoStuff();
    text = textBox.Text
    DoOtherStuff();
});

但是,正如評論中已經提到的那樣,明確地編寫方法可能會更好。 使用lambda表達式超出某一點會對代碼的可讀性產生負面影響。 使用lambda表達式當然很容易引入重復的代碼。

Control.Invoke()方法返回被調用方法的值。 這簡單易行:

        string value = (string)this.Invoke(new Func<string>(() => textBox1.Text));

或者更明確一點:

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) {
        var dlg = new Func<string>(GetText);
        string value = (string)this.Invoke(dlg);
    }
    private string GetText() {
        return textBox1.Text;
    }

您可以將委托傳遞給Invoke,該委托指向可以設置實例變量以保存文本值的方法,例如

    public Form1()
    {
        InitializeComponent();

        Invoke(new Action(SetTextboxTextVariable));
    }

    private string _text;

    private void SetTextboxTextVariable()
    {
        _text = txtBox.Text;
    } 

這涵蓋了基本思想,同步和通知其他線程取決於您。 :)

更新

或者一步到位:

    public Form1()
    {
        InitializeComponent();

        string text = GetText();
    }

    private string GetText()
    {
        string text;

        Invoke(new Action(text = txtBox.Text));

        return text;
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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