これはクラスでまとめるのに十分簡単です。ただし、目的のイベントをサブスクライブする前に、すべてのイベント ハンドラーを 1 つのイベント ハンドラーに集約する必要があります。
これを示す簡単なクラスを次に示します。提供された最初のイベントはイベント呼び出しとインラインで実行されますが、他のすべてのイベントはデフォルトのスレッド プールで実行されます。
class ParallelEvent<TEventArg> where TEventArg : EventArgs
{
private readonly EventHandler<TEventArg> _handler1;
private readonly EventHandler<TEventArg>[] _moreHandlers;
public ParallelEvent(EventHandler<TEventArg> handler1, params EventHandler<TEventArg>[] moreHandlers)
{
if (handler1 == null)
throw new ArgumentNullException("handler1");
if (moreHandlers == null)
throw new ArgumentNullException("moreHandlers");
_handler1 = handler1;
_moreHandlers = moreHandlers;
}
public void Handler(Object sender, TEventArg args)
{
IAsyncResult[] asyncResults = new IAsyncResult[_moreHandlers.Length];
for (int i = 0; i < _moreHandlers.Length; i++)
asyncResults[i] = _moreHandlers[i].BeginInvoke(sender, args, null, null);
_handler1(sender, args);
for (int i = 0; i < _moreHandlers.Length; i++)
_moreHandlers[i].EndInvoke(asyncResults[i]);
}
}
これを使用するために、並行して実行するすべてのイベント ハンドラーを提供する ParallelEvent クラスを作成します。次に、クラスの Handler メソッドを使用してイベント「test」をサブスクライブします。最後に、イベントを「test」と呼び、出力を確認します。次の例を検討してください。
private static event EventHandler<EventArgs> test;
static void Main()
{
var e = new ParallelEvent<EventArgs>(Test1, Test2);
test += e.Handler;
test(null, EventArgs.Empty);
}
static void Test1(Object sender, EventArgs args)
{
Console.WriteLine("Start Test 1");
Thread.Sleep(100);
Console.WriteLine("End Test 1");
}
static void Test2(Object sender, EventArgs args)
{
Console.WriteLine("Start Test 2");
Thread.Sleep(100);
Console.WriteLine("End Test 2");
}
予想どおり、上記のプログラムは、次の出力で示されるようにそれらを並行して実行します。
Start Test 1
Start Test 2
End Test 2
End Test 1
最後に、マルチスレッド コードに関する他の懸念事項に注意する必要があります。変更された共有状態は、同期する必要があります。
ちょっとした作業で、上記のクラスを調整してイベントを公開し、リスナーが自由に購読および購読解除できるようにすることができます。次に、Handler メソッドで、Delgate.GetInvocationList () を介してデリゲート リストを抽出します。デリゲートのリストを取得したら、上記の既存の Handler メソッドと同じように処理できます。