Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/294.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在多层体系结构中通过代理在线程之间进行通信?_C#_Multithreading - Fatal编程技术网

C# 在多层体系结构中通过代理在线程之间进行通信?

C# 在多层体系结构中通过代理在线程之间进行通信?,c#,multithreading,C#,Multithreading,我正在寻找线程间通信的解决方案。 我们有一个三层架构 桂,, 参考资料 逻辑 参考资料 设备控制器 线程A是windows应用程序的主线程。我启动一个独立于线程a的线程B,它们不共享代码。但是线程A必须得到一些关于线程b状态的反馈。我试图与一名代表一起解决这个问题。我必须在.NET3.5、c#、WEC7上工作 Gui和逻辑在线程A的上下文中运行 DeviceController在线程B的上下文中运行。两个线程都长时间运行 线程A启动并控制线程B。 线程A(逻辑)从B(DeviceControll

我正在寻找线程间通信的解决方案。 我们有一个三层架构

桂,, 参考资料 逻辑 参考资料 设备控制器

线程A是windows应用程序的主线程。我启动一个独立于线程a的线程B,它们不共享代码。但是线程A必须得到一些关于线程b状态的反馈。我试图与一名代表一起解决这个问题。我必须在.NET3.5、c#、WEC7上工作

Gui和逻辑在线程A的上下文中运行 DeviceController在线程B的上下文中运行。两个线程都长时间运行 线程A启动并控制线程B。 线程A(逻辑)从B(DeviceController)获取信息并更新Gui或数据库

在线程中执行代码是很重要的

    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);
        }
    }
}
//在线程B的上下文中运行 命名空间设备控制器 {

}

有两个问题我还不能处理:

No 1:OnMyEvent仍然在线程b的上下文中运行
第2点:我需要另一种方式的相同通信,如果gui中有一些事件,则必须通知devicecontroller,例如关机等。

如果线程A是gui线程,则可以使用Control.BeginInvoke向UI线程发送委托调用

您只需使GUI控件的一个实例可以从线程B访问。然后,只要该控件可见,您就可以在该实例上调用BeginInvoke

要与设备控制器通信,您可能必须创建一个同步队列


Net中的类提供了这方面的基础,并且有一个将用于从其他线程分派到UI线程的实现。但是,要使它以另一种方式工作,您可能需要编写自己的实现。

您的两个查询都与SynchronizationContext相关。请查看此代码项目文章:。顺便说一句,TPL使这一切变得容易多了。像从UIThread到线程B这样使用委托是不可能的?我刚刚感到了Wec7不支持ParameterizedThreadStart的痛苦。有人知道该怎么做,在WEC7上运行吗?@Traveler当然不可能直接运行。SynchronizationContext仅支持将内容分派到UIThread。要以另一种方式执行此操作,您必须编写自己的调度队列,该队列将从线程B轮询。
//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);