如何使用 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 11:41:20  来源:igfitidea点击:

How to use BeginInvoke C#

c#begininvoke

提问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 begininvokeexactly? What is Actiontype? Why there is blank brackets ()? And what does this mean =>?

你能告诉我具体怎么用begininvoke吗?什么是Action类型?为什么有空括号()?这是什么意思=>

采纳答案by P.Brian.Mackey

Actionis a Type of Delegate provided by the .NET framework. The Actionpoints 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 Delegateso Actioncan be used to wrap the lambda expression and provide the expected Typeto Invoke()

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

Invokecauses said Actionto 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 Rtfproperty on a RichTextBoxwhen an Invoke is necessary, without first calling Invoke, then a Cross-thread operation not validexception will be thrown. Check Control.InvokeRequiredbefore calling Invoke.

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

BeginInvokeis 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 BeginInvokeif 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 BeginInvokeis called for Delegatetype the delegate is just invoked asynchronously.
(Invokefor the sync version.)

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

If you want more universal code which works perfectly for WPF and WinForms you can consider Task Parallel Library and running the Taskwith 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 varwith lambdas: compiler needs a hint.

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

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.

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