使用事件进行C#线程通信

时间:2013-02-06 17:02:04

标签: c# multithreading thread-safety

我想在下面实现一些生活 -

enter image description here

我的应用程序将启动UI模块,从UI模块我将启动核心模块。核心模块将继续在不同的线程上运行。关于核心模块中的具体操作,我想提出将由UI模块订阅的事件。

基本上,我想将特定的枚举信息发送到UI模块。

请为我推荐一个型号。我正在努力实现它。

这个模块中的两个模块都会运行任何阻塞吗?

提前致谢

4 个答案:

答案 0 :(得分:1)

您可以使用带有Progress界面的IProgress类来完成此操作。

  1. 在您的UI上下文中,创建一个Progress对象,其中包含您需要传递的任何数据的泛型参数。

  2. 订阅活动,以便在后台任务更新时执行您想要执行的操作。

  3. 让后台任务接受IProgress类型的对象(Progress实施)并定期Report包含相关数据。

  4. ProgressChanged事件将在调用Report时触发,Progress对象将捕获创建它的位置的当前同步上下文,这是一种说法的方式。该事件将在UI线程中触发。

答案 1 :(得分:1)

我建议使用BackgroundWorker类

查看本教程 http://www.dotnetperls.com/backgroundworker

班级参考 http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx

这是如何以简单的方式进行的:

  1. 打开您的用户界面表单(设计视图)
  2. 在您的UI表单上添加backgroundworker控件
  3. 打开属性窗格并切换到事件(闪电图标)
  4. 双击dowork和runworkercompleted事件(这将生成事件处理程序)
  5. 转到事件处理程序(代码中)
  6. 现在在dowork处理程序中编写处理代码,并将要发送的结果添加到您的ui模块,如e.Result = your_enum(或任何其他对象);
  7. 接下来是runworkercompleted处理程序,并将RunWorkerCompletedEventArgs e(RunWorkerCompletedEventArgs对象)强制转换为枚举(或从dowork处理程序返回的对象),并根据需要在UI中使用它。
  8. 最后不要忘记启动后台工作者:来自你的UI mdoule的backgroundWorker1.RunWorkerAsync()
  9. 备注:如果需要定期报告进度,请使用BackgroundWorker类的ReportProgress方法。此方法有两个重载: 1)http://msdn.microsoft.com/en-us/library/ka89zff4.aspx 2)http://msdn.microsoft.com/en-us/library/a3zbdb1t.aspx

    第一个允许仅报告进度百分比,第二个允许您传入任何对象,如果您将

答案 2 :(得分:0)

System.Threading.ThreadBackgroundWorkerTask类来说,这应该很容易。您可以使用其中任何一个在另一个线程上运行代码。

当您需要通知用户界面时,只需举起一个活动。要建立活动,请看一下:

How can I make my own event in C#?

然后,您只需要确保调用Invoke以确保在正确的线程上执行最终的UI更新代码。为此,请看一下:

Thread Control.Invoke

答案 3 :(得分:0)

听起来像是对我的经典使用Mediator模式。 Mediator允许断开连接的组件相互通信。

我碰巧在我自己的MVVM框架中有一个这样的副本,你可以从这里获取:

http://cinch.codeplex.com/SourceControl/changeset/view/70832#796984

也抓住这个

http://cinch.codeplex.com/SourceControl/changeset/view/70832#797008

我的实现允许您使用WeakReference执行此操作,因此不会保留强引用。它还允许订阅者使用属性连接方法来侦听某些事件,并允许发布者广播新的T语言。

发布者/订阅者只需向Mediator注册

//done by both subscriber and publisher
Mediator.Instance.Register(this);


//Subscriber
[MediatorMessageSinkAttribute("DoBackgroundCheck")]
void OnBackgroundCheck(string someValue) { ... }


//publisher might typically do this
mediator.NotifyColleagues("DoBackgroundCheck", "Nice message");

当订阅者收到消息(WPF / Winforms预先构建了这些消息)时,您可能需要使用自己的SynchronizationContext来调用正确的线程。

我还允许同步/异步调用