[英]How can I access the ui thread in an asynchronous httpwebrequest callback in a bho
[英]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.