[英]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.