C#使用事件的线程通信

C#使用事件的线程通信,c#,multithreading,thread-safety,C#,Multithreading,Thread Safety,我想在生活中有所成就- 我的应用程序将启动UI模块,从UI模块我将启动核心模块。核心模块将继续在不同的线程上运行。关于核心模块中的具体操作,我想提出和事件,该事件将由UI模块订阅 基本上,我想将特定的枚举信息发送到UI模块 请给我推荐一个模型。我正在努力实现它 在这个模型中,这两个模块都会运行吗 提前感谢使用System.Threading.Thread或BackgroundWorker或Task类,这应该很容易做到。您可以使用它们中的任何一个在另一个线程上运行代码 当您需要通知UI时,只需引

我想在生活中有所成就-

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

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

请给我推荐一个模型。我正在努力实现它

在这个模型中,这两个模块都会运行吗


提前感谢

使用
System.Threading.Thread
BackgroundWorker
Task
类,这应该很容易做到。您可以使用它们中的任何一个在另一个线程上运行代码

当您需要通知UI时,只需引发一个事件。要构建事件,请查看以下内容:

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


对我来说,这听起来像是中介模式的经典用法。中介允许断开连接的组件相互通信

我恰好在自己的MVVM框架中有一个副本,您可以从这里获取:

也抓住这个

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

发布者/订阅者只需向中介注册即可

//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已经预先构建了这些消息)来调度对正确线程的调用


我还允许同步/A同步调用

您可以使用
进程
类和
I进程
界面来完成这项操作

  • 在您的UI上下文中,创建一个
    Progress
    对象,该对象带有一个通用参数,该参数包含您需要传递的任何数据

  • 订阅它的事件,以便在后台任务更新时执行任何您想执行的操作

  • 让后台任务接受类型为
    IProgress
    (由
    Progress
    实现)的对象,并让其定期
    报告相关数据


  • 每当调用
    Report
    时,就会触发
    ProgressChanged
    事件,
    Progress
    对象将捕获创建它的当前同步上下文,这是一种奇特的说法,表示事件将在UI线程中触发。

    我建议使用BackgroundWorker类

    签出此教程

    课堂参考

    以下是它的简单方式:

  • 打开您的UI表单(设计视图)
  • 在UI窗体上添加backgroundworker控件
  • 打开属性窗格并切换到事件(闪电图标)
  • 双击dowork和runworkercompleted事件(这将生成事件处理程序)
  • 转到事件处理程序(在代码中)
  • 现在,在dowork handler中编写处理代码,并添加要发送到ui模块的结果,如so e.result=your_enum(或任何其他对象)
  • 接下来,转到runworkercompleted处理程序,将RunWorkerCompletedEventArgs e(RunWorkerCompletedEventArgs对象)类型转换为枚举(或从dowork处理程序返回的对象),并根据需要在UI中使用它
  • 最后,不要忘记从UI mdoule启动backgroundworker:backgroundWorker1.RunWorkerAsync()
  • 备注:如果需要定期报告进度,请使用BackgroundWorker类的ReportProgress方法。此方法有两个重载: 1) (二)


    第一个只允许报告进度百分比,第二个可以用来传递任何对象,如果你愿意

    为什么要在框架中内置了
    progress
    类来为你做这件事?是的,对不起,我想我误解了他的意图。我所建议的仍然是在断开连接的模块之间进行通信的非常有效的方法。甚至在不同的集会上说。中介模式是一种强大的东西,但确实如此,你的建议最好是在这种情况下,他的背景任务是定期报告进度,BGW支持,但你在这里没有讨论。这将增加几个步骤。后台工作人员将不在这里工作。因为这是一个永无止境的过程。核心模块将继续运行,直到应用程序运行。因此,请使用ReportProgress方法(第二次重载)(其作用与调用相同),并可用于将userobject发送到ui线程,并使ui线程更新ui,这就是您想要的。注意:BackgroundWorker只是低级线程上的一个抽象,因此即使它是一个永不结束的进程,并且会随着进程的结束而结束,它也可以运行