毎度お世話になっております。Ryznaと申します。
タイトルに一言で表せなかったので改めて質問内容です。
環境:
言語:C#
.net framework:4.5.2
実装したいところ:WCFサービスから参照されるDLL内
質問内容:
メソッドMを実行するとイベントEが発生するような実装のクラスAがあるとします。
クラスAから2つのインスタンス(それぞれインスタンス1,インスタンス2)を作成します。
インスタンス1.イベントEが発生した場合にインスタンス2.メソッドMを実行し、逆に、
インスタンス2.イベントEが発生した場合にインスタンス1.メソッドMを実行したいとします。
Eイベントから実行されたMメソッドが発生させるEイベントは処理したくないとします。
当然このままでは相互にイベントが発生し続けて無限ループになってしまうのでこれを回避するためにどのような実装をするべきなのでしょうか。
補足と現状での考え:
このプログラムはマルチスレッドで実行されており、当然別クラスからも呼ばれることも想定しておりますので、とりあえずロック内でイベントハンドラを一時的に回避するor「イベントを処理しない」フラグによる判定は思いついているのですがこれでいいのかなぁと自信がない次第です。
Aクラスは自前のクラスですので手を入れられない訳ではないのですが、既にリリースされているものであり出来れば手を入れずに済めばなぁと考えております。
そもそも根本の実装を修正しなきゃダメという情報でも構いませんので皆様のお知恵を拝借できればと思います。
よろしくお願いします。
以上
追記:
4/15 19:30 頃までにご提案頂いた方法の中からベストアンサーを決定させていただきます。
それ以降も継続してご意見ご提案の募集は継続させて頂きます。よろしくお願いします。
追記2:
4/15 20:00の時点でご提案いただいていた3つの方法のうち、
・既存コードに手を加えない
・一連のフローの中で切り替えが行える
・クラスAと異なる構造でも適用できる
の3つの点でtorakichiさんの案をベストアンサーとさせていただきました。
もっといい方法があるよ!というご提案は引き続き募集させていただきますのでぜひご投稿いただければと思います。
追記3:
以下サンプルです。
lang
1// 既存のクラス 2// 既にリリース済み別案件で使用中なので出来れば手を入れたくない。入れちゃダメというわけでもない 3public class ClassA 4{ 5 public event EventHandler EventE; 6 7 public void MethodM() 8 { 9 var e = new EventArgs(); 10 11 // MethodM内のいろいろ処理 12 13 OnEventE(e); 14 } 15 16 protected virtual OnEventE(EventArgs e) 17 { 18 // OnEventE内のいろいろ処理 19 20 if (EventE != null) 21 EventE(this, e); 22 } 23} 24 25// ものすごく簡略化した新規コード 26public class Hoge 27{ 28 private ClassA _instance1; 29 private ClassA _instance2; 30 31 public Hoge() 32 { 33 _instance1 = new ClassA(); 34 _instance2 = new ClassA(); 35 } 36 37 private void Instance1_EventE(object obj, EventArgs e) 38 { 39 // インスタンス1.EventE発生時のいろいろ処理 40 41 _instance2.MethodM(); // ここでは_isntance2.EventEが発生してほしくない 42 } 43 44 private void Instance2_EventE(object obj, EventArgs e) 45 { 46 // インスタンス2.EventE発生時のいろいろ処理 47 48 _instance1.MethodM(); // ここでは_isntance1.EventEが発生してほしくない 49 } 50 51 public void MethodA() 52 { 53 // Hoge.MethodAとしていろいろ処理 54 55 _instance1.MethodM(); // ここでは_isntance1.EventEが発生してほしい 56 } 57 58 public void MethodB() 59 { 60 // Hoge.MethodBとしていろいろ処理 61 62 _instance2.MethodM(); // ここでは_isntance2.EventEが発生してほしい 63 } 64} 65
この状態のままMethodA,Bのどちらかを実行したら、当然相互にイベントが発生し続けてしまうわけで、それは困るということです。
現状はこのInstance1_EventE,Instance2_EventEの中でReaderWriterLock(実コードにてそういうロックが必要なのでそのまま流用しています。)のWriterでロックを掛けておいて、さらにその中でイベントハンドラの解除・追加を行うようにしていますが、それ以外に良い方法は無いかなぁと模索している状況です。
回答4件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/04/16 02:12