0

何かを確認したい - メソッドをイベントのサブスクライバーとして登録すると、次のようになります。

_serviceContext.ReadingEntity += new EventHandler<ReadingWritingEntityEventArgs>(_serviceContext_ReadingEntity);

次のように、イベントが発生したときに引き続き呼び出されたくない場合は、イベントのサブスクリプションからそのメソッドを登録解除する必要があります。

_serviceContext.ReadingEntity -= new EventHandler<ReadingWritingEntityEventArgs>(_serviceContext_ReadingEntity);

デリゲートをイベントのサブスクライバーとして登録すると、次のようになります。

public guy ThisMethod()
{
    _serviceContext.ReadingEntity += delegate(object sender, ReadingWritingEntityEventArgs e)
        {

        };
}

そのメソッドのサブスクライバー リストからそのデリゲートを登録解除する方法はありません。したがって、この登録の範囲は、登録されているメソッドに限定されていると想定しています。つまり、ThisMethod によって呼び出されたメソッドで _serviceContext.ReadingEntity イベントが発生した場合、この登録は既に期限切れになり、デリゲート内のコードは無効になります。走る。これは正しいです?

ありがとう!

ps イベントハンドラーを登録する最初の「長い」方法にもスコープの制限があることを認識していますが、それについては少し漠然としています。ただし、私の主な質問は、デリゲート登録が上記の方法の外で存続するかどうかです。

4

2 に答える 2

1

デリゲートへの参照を保持している場合は、デリゲートのサブスクライブを解除できます。

EventHandler<ReadingWritingEntityEventArgs> aDelegate = delegate(object sender, ReadingWritingEntityEventArgs e)
    {

    };
_serviceContext.ReadingEntity += aDelegate;
_serviceContext.ReadingEntity -= aDelegate;

このようにしないと、購読を解除する方法がありません。範囲は、登録された方法に限定されません。イベント期間中登録されます。

于 2012-08-25T23:15:39.377 に答える
1

この方法でデリゲートをサブスクライブすると (-=デリゲート変数をどこかにキャッシュする場合は、演算子を使用してサブスクライブを解除できます)、サブスクライバー リストからそれを削除することはできず、パブリッシャーが有効になるまでイベントが発生するたびに呼び出されます。さらに、このサブスクリプションは、パブリッシャーが有効になるまで (静的メソッドを使用しない限り)、サブスクライバー クラス (イベントにサブスクライブしたメソッドを含むクラス) のガベージ コレクションを防ぎます。

明確にするために、IL コードには「匿名」メソッドはありません。すべてのデリゲートと lamdbas は、静的/インスタンス メソッドとクロージャー クラスに変換されます (インスタンス メンバー/関数パラメーターを使用するかどうかによって異なります)。

于 2012-08-25T23:10:59.207 に答える