我正在寻找Interthread通信的解决方案。 我们有三层架构,
桂 引用 逻辑 引用 Devicecontroller
线程A是Windows应用程序的主线程。我启动一个独立于线程a的线程B,它们不共享代码。但是线程A必须得到一些关于线程b状态的反馈。我试着用代表来解决这个问题。我必须研究.net 3.5,c#,WEC7
Gui和Logic在线程A的上下文中运行 DeviceController在线程B的上下文中运行。两个线程都在长时间运行 线程A启动并控制线程B. 线程A(逻辑)从B(DeviceController)获取信息并更新Gui或数据库
在线程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);
}
}
}
//在线程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);
}
有两个问题,我还不能处理:
否1:OnMyEvent仍然在线程b的上下文中运行 否2:我需要以相反的方式进行相同的通信,如果gui中存在某些事件,则必须通知设备控制器例如关机等。
答案 0 :(得分:0)
如果线程A是GUI线程,则可以使用Control.BeginInvoke将委托调用分派给UI线程。
你只需要从你的线程B中创建一个GUI控件实例即可。只要该控件是可见的,你就可以在其上调用BeginInvoke。
要与设备控制器通信,您可能需要创建一个同步队列。
.Net中的SynchronizationContext类为此提供了基础,并且具有可用于从其他线程调度到UI线程的实现。但是为了让它以相反的方式工作,你可能必须编写自己的实现。