如何使用BeginInvoke C#

时间:2013-01-17 21:07:15

标签: c# begininvoke

请你帮我解释一下:

someformobj.BeginInvoke((Action)(() =>
{
    someformobj.listBox1.SelectedIndex = 0;
}));

你能告诉我如何准确使用begininvoke吗? 什么是Action类型? 为什么有空括号()? 这意味着什么=>

2 个答案:

答案 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

BeginInvokeInvoke的异步版本。异步意味着线程不会阻塞调用者,而不是阻塞的同步调用。

答案 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