2013-10-26 7 views
0

Я ищу решение для Interthread общения. Мы получили трехуровневую архитектуру,Связь между потоками через делегатов в многоуровневой архитектуре?

Гуй, референции Логические ссылки Devicecontroller

Thread А основной поток из окна приложения. Я запускаю Thread B, который работает независимо от потока a, они не используют код. Но нить A должна получить некоторую обратную связь о состоянии потока b. Я пытаюсь решить это с помощью делегата. Я должен работать на .NET 3.5, C#, WEC7

Гуй и логика запуска в контексте нитяным DeviceController работает в контексте темы B. Обе Резьбы длинные хода начинается Пронизывайте и управления Thread B. Thread A (Logic) получает информацию обратно из B (DeviceController) и обновляет Гуй или базу данных

важно, что код выполняется в нитяном

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 все еще работает в контексте потока б № 2: Мне нужно то же сообщение другой Кстати, если в gui есть какое-то событие, devicecontroller должен быть проинформирован о, например, shutdown и т. д.

+0

Оба ваших вопроса связаны с SynchronizationContext. Взгляните на статью Code Project: http://www.codeproject.com/Articles/31971/Understanding-SynchronizationContext-Part-I. Btw, TPL делает все это намного проще. – bytefire

ответ

0

Если поток A представляет собой поток GUI, вы можете использовать Control.BeginInvoke для отправки делегатских вызовов в поток пользовательского интерфейса.

Вам просто нужно сделать экземпляр вашего элемента управления GUI доступным из вашего потока B. Затем вы можете вызвать BeginInvoke на нем, пока этот элемент управления является видимым.

Для связи с контроллером устройства вам, вероятно, придется создать синхронизированную очередь.

SynchronizationContext класс в .Net обеспечивает основу для этого и имеет реализацию, которая будет работать для отправки из другого потока в поток пользовательского интерфейса. Но чтобы заставить его работать наоборот, вам, возможно, придется написать свою собственную реализацию.

+0

Невозможно использовать делегат так же, как путь от UIThread до Thread B? – traveller

+0

Я только что почувствовал боль, которую Wec7 не поддерживает ParameterizedThreadStart. Кто-нибудь знает, что делать вместо этого, чтобы сделать это на WEC7? – traveller

+0

@traveller, конечно, это невозможно напрямую. SynchronizationContext поддерживает только отправку сообщений только в UIThread. Для этого вы должны написать свою собственную очередь отправки, которая будет опрошена из Thread B. – Rakhitha

Смежные вопросы