イベント デリゲートのサブスクライバー リストを反復処理するために必要なコードを静的ヘルパー ルーチンにラップしようとしています。これにより、多くのイベント ハンドラーに対して同じコードをコピーして貼り付ける必要がなくなります。私はまだ C# の詳細を学んでおり、詳細につまずいています。
ヘルパー ルーチンは、イベント サブスクライバー リストを反復処理し、各サブスクライバーを個別に呼び出して、サブスクライバーのスレッドを自動的に同期できるようにします。イベントの多くは、GUI のさまざまなフォームからサブスクライブされるため、各フォーム クラスでイベントのスレッド同期を管理する必要がなくなります。
以下のコードは、概念の例を示しています。最後の行....
singleCast.Invoke(paramList);
...明らかに、いくつかの理由で有効ではありません。
非常に遅いことがわかっている DynamicInvoke メソッドを使用せずに、各サブスクライバーを呼び出すにはどうすればよいですか?
ForEach が特定のイベント Delegates とジェネリック Delegates を返すように型参照を渡す方法はありますか?
以下のコード例を参照してください。
namespace Reflection_Diagnostics
{
// ***********************
// *** Event Delegates ***
// ***********************
public delegate void SystemPoll();
public delegate void SystemStart(int option);
public delegate void SystemEnd();
class clsTestEvents
{
// **************
// *** Events ***
// **************
public event SystemPoll Event_SystemPoll;
public event SystemStart Event_SystemStart;
public event SystemEnd Event_SystemEnd;
// ***********************
// *** Event Overrides ***
// ***********************
private void OnEvent_SystemPoll() // Event Override
{
MyToolBox.SyncEvents(Event_SystemPoll);
}
private void OnEvent_SystemStart(int option) // Event Override
{
MyToolBox.SyncEvents(Event_SystemStart, option);
}
private void OnEvent_SystemEnd() // Event Override
{
MyToolBox.SyncEvents(Event_SystemEnd);
}
// ***********************
// *** Test The Events ***
// ***********************
public void TestTheEvents()
{
Event_SystemPoll();
Event_SystemStart(1);
Event_SystemEnd();
}
}
public class MyToolBox
{
// *******************
// *** Sync Events ***
// *******************
// Iterate through the event subscriber list and synchronize to the subscriber thread when needed
static public void SyncEvents(Delegate handler, params object[] paramList)
{
if (null != handler)
{
foreach (Delegate singleCast in handler.GetInvocationList())
{
ISynchronizeInvoke syncInvoke = singleCast.Target as ISynchronizeInvoke;
try
{
if ((syncInvoke != null) && (syncInvoke.InvokeRequired))
{
syncInvoke.Invoke(singleCast, paramList); // Subscriber is on a different thread
}
else
{
// Error: System.Delegate does not contain a definition for 'Invoke'.....
// singleCast is a generic Delegate, and so cannot be directly invoked.
// DynamicInvoke is avialable, but is much, MUCH, MUCH!! slower to execute
singleCast.Invoke(paramList); // Subscriber is on the same thread
}
}
catch
{
}
}
}
}
}
}