请你帮我解释一下:
someformobj.BeginInvoke((Action)(() =>
{
someformobj.listBox1.SelectedIndex = 0;
}));
你能告诉我如何准确使用begininvoke
吗?
什么是Action
类型?
为什么有空括号()
?
这意味着什么=>
?
答案 0 :(得分:73)
Action
是.NET框架提供的代理类型。 Action
指向没有参数的方法,并且不返回值。
() =>
是lambda expression语法。 Lambda表达式不是Delegate
类型。调用需要Delegate
,因此可以使用Action
来包装lambda表达式并将Type
提供给Invoke()
Invoke
导致所述Action
在创建Control的窗口句柄的线程上执行。通常需要更改线程以避免Exceptions
。例如,如果在需要Invoke时尝试在Rtf
上设置RichTextBox
属性,而不先调用Invoke,则会抛出Cross-thread operation not valid
异常。在调用Invoke之前检查Control.InvokeRequired
。
BeginInvoke
是Invoke
的异步版本。异步意味着线程不会阻塞调用者,而不是阻塞的同步调用。
答案 1 :(得分:10)
我猜你的代码与Windows Forms有关
如果需要在UI线程中异步执行某些操作,则调用BeginInvoke
:在大多数情况下更改控件的属性。
粗略地说,这是通过将委托传递给定期执行的某个过程来实现的。 (消息循环处理和类似的东西)
如果为BeginInvoke
类型调用Delegate
,则只是异步调用委托。
(Invoke
用于同步版本。)
如果您想要更多适用于WPF和WinForms的通用代码,您可以考虑使用任务并行库并使用context运行Task
。 (TaskScheduler.FromCurrentSynchronizationContext()
)
并添加一点其他人已经说过:
Lambdas可以作为匿名方法或expressions来对待
这就是为什么你不能只将var
与lambdas一起使用:编译器需要提示。
<强>更新强>
这需要.Net v4.0及更高版本
// This line must be called in UI thread to get correct scheduler
var scheduler = System.Threading.Tasks.TaskScheduler.FromCurrentSynchronizationContext();
// this can be called anywhere
var task = new System.Threading.Tasks.Task( () => someformobj.listBox1.SelectedIndex = 0);
// also can be called anywhere. Task will be scheduled for execution.
// And *IF I'm not mistaken* can be (or even will be executed synchronously)
// if this call is made from GUI thread. (to be checked)
task.Start(scheduler);
如果你从其他线程启动任务并需要等待它的completition task.Wait()
将阻止调用线程直到任务结束。
详细了解任务here。