如何使用 BeginInvoke C#
Posted
技术标签:
【中文标题】如何使用 BeginInvoke C#【英文标题】:How to use BeginInvoke C# 【发布时间】:2013-01-01 12:38:21 【问题描述】:您能帮我解释一下吗:
someformobj.BeginInvoke((Action)(() =>
someformobj.listBox1.SelectedIndex = 0;
));
您能告诉我如何准确地使用begininvoke
吗?
什么是Action
类型?
为什么有空括号()
?
=>
是什么意思?
【问题讨论】:
一篇文章中有这么多不同的问题...... - 应该至少有 3 个单独的问题 也看看这篇文章mark-dot-net.blogspot.com.uy/2014/07/… 【参考方案1】:Action
是 .NET 框架提供的委托类型。 Action
指向一个没有参数且不返回值的方法。
() =>
是 lambda expression 语法。 Lambda 表达式不属于 Delegate
类型。调用需要Delegate
,因此Action
可用于包装lambda 表达式并将预期的Type
提供给Invoke()
Invoke
导致Action
在创建控件窗口句柄的线程上执行。通常需要更改线程以避免Exceptions
。例如,如果在需要调用时尝试在RichTextBox
上设置Rtf
属性,而无需先调用Invoke,则将引发Cross-thread operation not valid
异常。在调用 Invoke 之前检查 Control.InvokeRequired
。
BeginInvoke
是 Invoke
的异步版本。异步意味着线程不会阻塞调用者,而不是阻塞的同步调用。
【讨论】:
所以如果我理解正确的话,Action是用来保证跨线程安全的,所以你会通过方法调用通知对象而不是自己设置值?此外,该方法将接受任何委托,而不仅仅是具体的 Action,是吗? @KyleBaran -Action
与线程安全无关,即Invoke
。 Invoke
接受 Delegate
作为参数。所以任何可转换为Delegate
的东西都可以作为参数传递。
@KyleBaran Action 只是一个内置的委托类型,您可以将其替换为:delegate void mydlg();调用((mydlg)(() => ));【参考方案2】:
我猜您的代码与 Windows 窗体有关。
如果您需要在 UI 线程中异步执行某些内容,请调用 BeginInvoke
:在大多数情况下更改控件的属性。
粗略地说,这是通过将委托传递给某个定期执行的过程来完成的。 (消息循环处理之类的东西)
如果为Delegate
类型调用BeginInvoke
,则委托只是异步调用。
(Invoke
用于同步版本。)
如果您想要更多适用于 WPF 和 WinForms 的通用代码,您可以考虑使用任务并行库并运行 Task
和相应的 context。 (TaskScheduler.FromCurrentSynchronizationContext()
)
在其他人已经说过的基础上再补充一点:
Lambda 可以被视为匿名方法或expressions。
这就是为什么您不能只将 var
与 lambda 一起使用:编译器需要提示。
更新:
这需要 .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()
将阻塞调用线程直到任务结束。
阅读更多关于任务here。
【讨论】:
你能给我一些例子吗?以上是关于如何使用 BeginInvoke C#的主要内容,如果未能解决你的问题,请参考以下文章
c#的BeginInvoke和EndInvoke使用demo