2013-10-26 28 views
0

我找了間通信的解決方案。 我們得到了一個三層結構體系,通過多層體系結構中的委託進行線程之間的通信?

桂, 引用 邏輯 引用 Devicecontroller

線程A是一個Windows應用程序的主線程。我開始一個獨立於線程a的線程B,它們不共享代碼。但是線程A必須得到關於線程b狀態的一些反饋。我試圖用一個委託來解決這個問題。我必須在.NET 3.5,C#工作,WEC7

在線程上下文

桂和邏輯過程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 的上下文名稱空間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

兩個你被查詢涉及的SynchronizationContext。看看這個代碼項目文章:http://www.codeproject.com/Articles/31971/Understanding-SynchronizationContext-Part-I。順便說一下,TPL使這一切變得更容易。 – bytefire

回答

0

如果線程A是GUI線程你可以使用Control.BeginInvoke派遣委託調用UI線程。

你必須讓你的GUI控件的一個實例是從你的線程B.訪問然後你可以只要對照可見調用BeginInvoke就可以了。

要與設備控制器進行通信,你可能要創建一個同步的隊列。

SynchronizationContext類在.net中提供了這個基礎,並具有將來自其他線程調度到UI線程工作的實現。但爲了使它在另一個方向上工作,可能需要編寫自己的實現。

+0

它不可能像這樣從UIThread到Thread B的方式使用委託這種方式? – traveller

+0

我剛剛感受到Wec7不支持ParameterizedThreadStart的痛苦。有人想知道該怎麼做,爲了使這個運行在WEC7上? – traveller

+0

@traveller當然是不可能的。 SynchronizationContext僅支持將事物分派給UIThread。要做到這一點,你必須編寫自己的調度隊列,將從線程B輪詢。 – Rakhitha