简体   繁体   English

通过多层体系结构中的委托进行线程之间的通信?

[英]Communication between threads via delegates in Multi Tier Architecture?

I am looking for a solution for Interthread communication. 我正在寻找线程间通信的解决方案。 We got a Three Tier Architecture, 我们有一个三层架构,

Gui, references Logic references Devicecontroller Gui,参考逻辑参考Devicecontroller

Thread A is the main thread of a windows app. 线程A是Windows应用程序的主线程。 I starts a Thread B that is working independant of thread a, they do not share code. 我启动了一个独立于线程a工作的线程B,它们不共享代码。 But thread A has to get some feedback about status of thread b. 但是线程A必须获得有关线程b状态的一些反馈。 I try to solve this with a delegate. 我尝试与代表解决这个问题。 I have to work on .net 3.5, c#, WEC7 我必须在.net 3.5,C#,WEC7上工作

Gui and Logic run in context of Thread A DeviceController runs in Context of Thread B. Both Threads are long running Thread A starts and controls Thread B. Thread A (Logic) gets information back from B (DeviceController) and updates the Gui or the database Gui和Logic在线程A的上下文中运行。DeviceController在线程B的上下文中运行。两个线程都长时间运行。线程A启动并控制线程B。线程A(逻辑)从B(DeviceController)获取信息,并更新Gui或数据库

It is important that the code is executed in Thread A 在线程A中执行代码很重要

    public void OnMyEvent(string foo)
    {
        //there may be access to Gui here, there may be other actions, like accessing database
        // All this should be in context of thread A
        MessageBox.Show(foo);
    }

// The Gui
namespace WindowsFormsApplication1
{
    //This code is executed in Thread A, UIThread
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            ThreadController threadController = new ThreadController();
            threadController.StartThread(this, e);
        }

    }

}

//Tier Logic, runs in Context of Thread A
namespace Logic
{
    //this class runs in the context of Thread A
    public  class ThreadController
    {
        public void StartThread(Object obj)
        {
            new ClassForSecondThread(obj as Parameters);
        }

        public void StartThread(object sender, EventArgs e)
        {
            //ParameterizedThreadStart threadstart = new ParameterizedThreadStart(startThread);
            ParameterizedThreadStart threadstart = new ParameterizedThreadStart(StartThread);
            Thread thread = new Thread(threadstart);
            Parameters parameters = new Parameters() {MyEventHandler = OnMyEvent};
            thread.Start(parameters);
        }

        public void OnMyEvent(string foo)
        {
            //there may be access to Gui here, there may be other actions, like accessing database
            // All this should be in context of thread A. Here it is unfortunately in Context Thread B
            MessageBox.Show(foo);
        }
    }
}

//runs in context of Thread B namespace DeviceController { //在线程B名称空间DeviceController {

//This class runs in the context of  Thread B
public class ClassForSecondThread
{
    public ClassForSecondThread(Parameters parameters)
    {
        if (parameters == null)
            return;
        MyEventhandler += parameters.MyEventHandler;
        DoWork();
    }

    private void DoWork()
    {
        //DoSomething
        if (MyEventhandler != null)
            MyEventhandler.DynamicInvoke("Hello World"); 
        Thread.Sleep(10000);
        if (MyEventhandler != null)
            MyEventhandler.DynamicInvoke("Hello World again");

    }

    private event MyEventHandler MyEventhandler;
}

public class Parameters
{
    public MyEventHandler MyEventHandler;
}

public delegate void MyEventHandler(string foo);

} }

There are two issues, I cannot yet handle: 有两个问题,我尚无法解决:

No 1: OnMyEvent still runs in context of thread b No 2: I need the same communication the other way, if there is some event in the gui, the devicecontroller has to be informed about eg shutdown etc. 否1:OnMyEvent仍在线程b的上下文中运行否2:我需要以另一种方式进行相同的通信,如果gui中存在某些事件,则必须通知设备控制器,例如关闭等。

If the thread A is the GUI thread you could use Control.BeginInvoke to dispatch delegate calls to UI thread. 如果线程A是GUI线程,则可以使用Control.BeginInvoke将委托调用分派到UI线程。

You just have to make an instance of your GUI control to be accessible from your thread B. Then you can call BeginInvoke on it as long as that control is Visible. 您只需创建GUI控件的实例即可从线程B进行访问。然后,只要该控件可见,就可以在其上调用BeginInvoke。

To communicate with device controller you will probably have to create a synchronized queue. 要与设备控制器通信,您可能必须创建一个同步队列。

SynchronizationContext class in .Net provide the basis for this and has an implementation that will work for dispatching from other thread to UI thread. .Net中的SynchronizationContext类提供了此基础,并且有一个实现将从其他线程分派到UI线程的实现。 But to make it work the other way around you may have to write your own implementation. 但是要使其以其他方式起作用,您可能必须编写自己的实现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM