0

スレッド間通信のソリューションを探しています。私たちは 3 層アーキテクチャを手に入れました。

Gui、リファレンス Logic リファレンス Devicecontroller

スレッド A は、Windows アプリのメイン スレッドです。スレッド a とは独立して動作しているスレッド B を開始します。これらはコードを共有しません。ただし、スレッド A は、スレッド b のステータスに関するフィードバックを取得する必要があります。これをデリゲートで解決しようとしています。.net 3.5、c#、WEC7 で作業する必要があります

Gui とロジックは、スレッド A のコンテキストで実行されます DeviceController は、スレッド B のコンテキストで実行されます。両方のスレッドが長時間実行されます。

コードがスレッド 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);

}

2 つの問題がありますが、まだ処理できません。

いいえ 1: OnMyEvent は引き続きスレッド b のコンテキストで実行されます いいえ 2: 逆に同じ通信が必要です。GUI に何らかのイベントがある場合、デバイスコントローラーにシャットダウンなどについて通知する必要があります。

4

1 に答える 1

0

スレッド A が GUI スレッドの場合、Control.BeginInvoke を使用してデリゲート呼び出しを UI スレッドにディスパッチできます。

スレッド B からアクセスできるように、GUI コントロールのインスタンスを作成するだけで済みます。その後、そのコントロールが Visible である限り、BeginInvoke を呼び出すことができます。

デバイス コントローラーと通信するには、おそらく同期キューを作成する必要があります。

.Net のSynchronizationContextクラスは、これの基礎を提供し、他のスレッドから UI スレッドへのディスパッチに機能する実装を備えています。しかし、それを逆に機能させるには、独自の実装を作成する必要がある場合があります。

于 2013-10-26T13:25:47.843 に答える