在 C# 中使事件异步的最佳方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/80645/
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-03 11:18:20  来源:igfitidea点击:

Best way to make events asynchronous in C#

提问by Niklas Winde

Events are synchronous in C#. I have this application where my main form starts a thread with a loop in it that listens to a stream. When something comes along on the stream an event is fired from the loop to the main form.

事件在 C# 中是同步的。我有这个应用程序,其中我的主窗体启动了一个线程,其中有一个循环监听流。当某些东西出现在流上时,一个事件会从循环触发到主窗体。

If the main form is slow or shows a messagebox or something the loop will be suspended. What is the best way around this? By using a callback and invoke on the main form?

如果主窗体很慢或显示消息框或其他东西,循环将被暂停。解决这个问题的最佳方法是什么?通过在主窗体上使用回调和调用?

采纳答案by Sam

Hmmm, I've used different scenarios that depended on what I needed at the time.

嗯,我使用了不同的场景,这取决于我当时的需要。

I believe the BeginInvoke would probably be the easiest to code since you're almost there. Either way you should be using Invoke already, so just changing to BeginInvoke. Using a callback on a separate thread will accomplish the same thing (as long as you use the threadpool to queue up the callback) as using BeginInvoke.

我相信 BeginInvoke 可能是最容易编写的代码,因为您快到了。无论哪种方式,您都应该已经在使用 Invoke,因此只需更改为 BeginInvoke。在单独的线程上使用回调将完成与使用 BeginInvoke 相同的事情(只要您使用线程池将回调排队)。

回答by jfs

Since you're using a form, the easier way is to use the BackgroundWorkercomponent.

由于您使用的是表单,因此更简单的方法是使用BackgroundWorker组件。

The BackgroundWorker class allows you to run an operation on a separate, dedicated thread. Time-consuming operations like downloads and database transactions can cause your user interface (UI) to seem as though it has stopped responding while they are running. When you want a responsive UI and you are faced with long delays associated with such operations, the BackgroundWorker class provides a convenient solution.

BackgroundWorker 类允许您在单独的专用线程上运行操作。下载和数据库事务等耗时操作可能会导致您的用户界面 (UI) 看起来好像在它们运行时已停止响应。当您需要响应式 UI 并且面临与此类操作相关的长时间延迟时,BackgroundWorker 类提供了一个方便的解决方案。

回答by Davy Landman

Events are just delegates, so use BeginInvoke. (see Making Asynchronous Method Calls in the .NET Environment)

事件只是委托,所以使用 BeginInvoke。(请参阅在 .NET 环境中进行异步方法调用

回答by Raithlin

You have a few options, as already detailed, but in my experience, you're better off leaving delegates and BeginInvoke, and using BackgroundWorker instead (v2.0+), as it is easier to use and also allows you to interact with the main form on the thread's completion. All in all a very weel implemented solution, I have found.

您有几个选项,已经详细说明,但根据我的经验,最好离开委托和 BeginInvoke,而使用 BackgroundWorker (v2.0+),因为它更易于使用并且还允许您与线程完成时的主要形式。总而言之,我发现了一个非常好实施的解决方案。

回答by el2iot2

System.ComponentModel.BackgroundWorkeris indeed a good starting point. It will do your asynchronous work, give you notifications of important events, and has ways to better integrate with your forms.

System.ComponentModel.BackgroundWorker确实是一个很好的起点。它将完成您的异步工作,为您提供重要事件的通知,并提供与您的表单更好地集成的方法。

For example, you can activate progress notifications by registering a handler for the ProgressChanged event. (which is highly recommended if you have a long, asynchronous process and you don't want your user to think the application froze)

例如,您可以通过为 ProgressChanged 事件注册处理程序来激活进度通知。(如果您有一个很长的异步进程,并且您不希望您的用户认为应用程序冻结,那么强烈建议您这样做)