2009-08-28 22 views
0

すべてのWaitOneとManualResetEventの作業が完了しました(ありがとう!)スレッドからクラスAの関数を実行している最後の問題がありますクラスBの一部である - 再び説明することができます。クラスBのスレッドからクラスAの関数を呼び出す[C#]

クラスA内の関数 "DoIt(obejct param)"を見てください。これは、クラスAによって呼び出される必要があります。クラスBのスレッド(図のように)...これはどのように達成できますか?デリゲートの何らかの形で助けてくれますか?

class A 
{ 
private ManualResetEvent manualResetEvent; 
int counter = 0; 

public A() 
    { 
    manualResetEvent = new ManualResetEvent(false); 
    B child = new B(manualResetEvent); 

    if (manualResetEvent.WaitOne(1000, false)) 
     { 
     ... do the work I was waiting on ... 
     } 

    ... do more work ... 
    // Call the function DoIt from within A // 
    DoIt(param) 

    } 

    // This is the function that needs to be called from A and thread in B 
    void DoIt(object param) 
    { 
    counter++; 
    ... do something with param with is local to A ... 
    } 

}; 


Class B 
{ 
private ManualResetEvent manualResetEvent; 

public B(ManualResetEvent mre) 
    { 
    manualResetEvent = mre; 
    Thread childThread = new Thread(new ThreadStart(Manage)); 
    childThread.IsBackground = true; 
    childThread.Name = "NamedPipe Manager"; 
    childThread.Start(); 

    private void Manage() 
     { 
     ... do some work ... 
     ... call some functions ... 

     // Calling the function from Class A, obviouslly doesn't work as-is 
     DoIt(param); 

     manualResetEvent.Set(); 

     ... do more work ... 
     ... call more functions ... 
     } 
    } 
}; 

どのようにスレッドセーフな方法でこのタスクを達成することができますか? ご協力いただければ幸いです。 ありがとう、

答えて

1

は、最も簡単な方法は、ちょうどあなたがmanualreseteventでやっように、あなたのオブジェクトBに渡すことであろうあなたの現在のデザインを考えます。

+0

"this"を渡して代わりにparent.manualResetEventを使用するほうがよいでしょうか?おそらく – Shaitan00

+0

。しかし、あなたが良いデザインに関心を持っているのであれば、ちょっとだけでなく、全体を再評価するべきでしょう。 – DSO

0

前の質問と同様に、メソッドの呼び出し先のAのインスタンスをBのコンストラクタに渡す必要があります。あなたがパブリックとしてA.DoItをマークする必要があります。もちろん、

B child = new B(this, manualResetEvent); 
... etc... 

Class B 
{ 
private A parent; 
private ManualResetEvent manualResetEvent; 

public B(A p, ManualResetEvent mre) 
{ 
    parent = p; 
    manualResetEvent = mre; 
    ... etc ... 


private void Manage() 
{ 
    ... do some work ... 
    ... call some functions ... 

    parent.DoIt(param); 

    ... etc... 

+0

私はいつもこのコードを渡すことは恐ろしいコードでした...うまくいけば、これは、5-10スレッド(クラスBのインスタンス)を持つことができるので、byvalではなくbyrefで行われます。 これはスレッドセーフ? 2人の子供(クラスB)が同時にA.DoIt(...)を呼び出すとどうなりますか? – Shaitan00

+0

一度に1つしか呼び出せないコードの回りにロックを使います。作業中に何をしているのかわからなければ、コードがスレッドセーフではない理由を知るのは難しいです。 –

+0

FUNCTIONをロックすることはできますか?またはDoItを使用するときにロック(親)自体を意味しますか? – Shaitan00

0

クラスAとクラスBの両方を操作する上位クラスが必要であると仮定していますか? GUIフォームやメインスレッドなど?

クラスBのイベントが定義されていると、作業が完了したときにトリガされます。あなたのフォームがイベントを聞いてきたら、クラスAの関数を呼び出してください。

あなたの2つのクラスがお互いに大きく依存しているかのように聞こえます。 Bでの作業がAの結果に依存し、その逆の場合は、クラスが実際にどのようにモジュール化されているかを再検討することができます。

+0

これはサービスです。上位クラス(サービスインターフェイス)はありますが、GUIはありません(コントロールなし)。 – Shaitan00

関連する問題