59

你能帮我解释一下吗:

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

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

4

2 回答 2

87

Action是 .NET 框架提供的一种委托类型。Action指向一个没有参数且不返回值的方法。

() =>lambda 表达式语法。Lambda 表达式不是 Type Delegate。Invoke requires DelegatesoAction可用于包装 lambda 表达式并提供预期TypeInvoke()

Invoke导致Action在创建控件窗口句柄的线程上执行。经常需要避免更改线程Exceptions。例如,如果在需要调用时尝试Rtf在 a 上设置属性RichTextBox,而无需先调用 Invoke,Cross-thread operation not valid则会引发异常。Control.InvokeRequired在调用 Invoke 之前检查。

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

于 2013-01-17T21:20:17.067 回答
13

我猜您的代码与 Windows 窗体有关。如果您需要在 UI 线程中异步执行某些内容,
您可以调用:在大多数情况下更改控件的属性。 粗略地说,这是通过将委托传递给某个定期执行的程序来完成的。(消息循环处理和类似的东西)BeginInvoke

如果BeginInvokeDelegate类型调用,则委托只是异步调用。
Invoke对于同步版本。)

如果您想要更多适用于 WPF 和 WinForms 的通用代码,您可以考虑任务并行库并使用Task相应的上下文运行。( TaskScheduler.FromCurrentSynchronizationContext())

并且补充一点其他人已经说过的: Lambdas 可以被视为匿名方法或表达式
这就是为什么你不能只使用varlambdas:编译器需要一个提示。

更新:

这需要 .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);

如果您从其他线程启动任务并且需要等待其完成task.Wait()将阻塞调用线程直到任务结束。

在此处阅读有关任务的更多信息。

于 2013-01-17T21:15:13.810 回答