如何使用 BeginInvoke C#
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14388136/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use BeginInvoke C#
提问by Mohammed Noureldin
Could you explain this for me please:
你能帮我解释一下吗:
someformobj.BeginInvoke((Action)(() =>
{
someformobj.listBox1.SelectedIndex = 0;
}));
Could you tell me how can I use begininvoke
exactly?
What is Action
type?
Why there is blank brackets ()
?
And what does this mean =>
?
你能告诉我具体怎么用begininvoke
吗?什么是Action
类型?为什么有空括号()
?这是什么意思=>
?
采纳答案by P.Brian.Mackey
Action
is a Type of Delegate provided by the .NET framework. The Action
points to a method with no parameters and does not return a value.
Action
是.NET 框架提供的一种委托类型。在Action
没有参数的方法分,不返回值。
() =>
is lambda expressionsyntax. Lambda expressions are not of Type Delegate
. Invoke requires Delegate
so Action
can be used to wrap the lambda expression and provide the expected Type
to Invoke()
() =>
是lambda 表达式语法。Lambda 表达式不是 Type Delegate
。Invoke requires Delegate
soAction
可用于包装 lambda 表达式并提供预期Type
的Invoke()
Invoke
causes said Action
to execute on the thread that created the Control's window handle. Changing threads is often necessary to avoid Exceptions
. For example, if one tries to set the Rtf
property on a RichTextBox
when an Invoke is necessary, without first calling Invoke, then a Cross-thread operation not valid
exception will be thrown. Check Control.InvokeRequired
before calling Invoke.
Invoke
表示Action
在创建控件窗口句柄的线程上执行的原因。通常需要更改线程以避免Exceptions
. 例如,如果在需要 Invoke 时尝试Rtf
在 a上设置属性RichTextBox
,而没有先调用 Invoke,Cross-thread operation not valid
则会引发异常。Control.InvokeRequired
在调用 Invoke 之前检查。
BeginInvoke
is the Asynchronous version of Invoke
. Asynchronous means the thread will not block the caller as opposed to a synchronous call which is blocking.
BeginInvoke
是 的异步版本Invoke
。异步意味着线程不会阻塞调用者,而不是阻塞的同步调用。
回答by Pavel Voronin
I guess your code relates to Windows Forms.
You call BeginInvoke
if you need something to be executed asynchronously in the UI thread: change control's properties in most of the cases.
Roughly speaking this is accomplished be passing the delegate to some procedure which is being periodically executed. (message loop processing and the stuff like that)
我猜您的代码与 Windows 窗体有关。如果您需要在 UI 线程中异步执行某些操作,
您可以调用BeginInvoke
:在大多数情况下更改控件的属性。
粗略地说,这是通过将委托传递给某个正在定期执行的过程来完成的。(消息循环处理之类的东西)
If BeginInvoke
is called for Delegate
type the delegate is just invoked asynchronously.
(Invoke
for the sync version.)
如果BeginInvoke
为Delegate
类型调用委托,则只是异步调用。
(Invoke
对于同步版本。)
If you want more universal code which works perfectly for WPF and WinForms you can consider Task Parallel Library and running the Task
with the according context. (TaskScheduler.FromCurrentSynchronizationContext()
)
如果您想要更多适用于 WPF 和 WinForms 的通用代码,您可以考虑使用 Task Parallel Library 并Task
使用相应的上下文运行。( TaskScheduler.FromCurrentSynchronizationContext()
)
And to add a little to already said by others:
Lambdas can be treated either as anonymous methods or expressions.
And that is why you cannot just use var
with lambdas: compiler needs a hint.
并补充一点其他人已经说过的:Lambdas 可以被视为匿名方法或表达式。
这就是为什么你不能只使用var
lambdas 的原因:编译器需要一个提示。
UPDATE:
更新:
this requires .Net v4.0 and higher
这需要 .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);
If you started the task from other thread and need to wait for its completition task.Wait()
will block calling thread till the end of the task.
如果您从其他线程启动任务并需要等待其完成task.Wait()
将阻塞调用线程直到任务结束。
Read more about tasks here.
在此处阅读有关任务的更多信息。