ビューモード クラス mvvm というクラスがあるとします。次に、この vm 用に作成されたいくつかのイベント ハンドラーがあります。その後、さまざまな状況で他の多くの人が使用できます。
したがって、myvm のインスタンスがある場合、接続されているイベント ハンドラーがあるかどうかを検出し、メモリの問題のためにそれを解放したいと考えています。
myvm からこれを行う一般的な方法は何ですか?たとえば、myvm のソース コードを持っていない可能性があります。
ビューモード クラス mvvm というクラスがあるとします。次に、この vm 用に作成されたいくつかのイベント ハンドラーがあります。その後、さまざまな状況で他の多くの人が使用できます。
したがって、myvm のインスタンスがある場合、接続されているイベント ハンドラーがあるかどうかを検出し、メモリの問題のためにそれを解放したいと考えています。
myvm からこれを行う一般的な方法は何ですか?たとえば、myvm のソース コードを持っていない可能性があります。
イベントは、イベントを宣言したクラス外のコードが基になるデリゲートにアクセスできないように設計されています。たとえば、C# 言語仕様のセクション「10.8 イベント」によると(強調は私のものです):
x += y または x -= y の形式の操作で、x がイベントであり、x の宣言を含む型の外部で参照が行われる場合、操作の結果は void 型になります ( x の型、代入後の x の値)。この規則は、外部コードがイベントの基になるデリゲートを間接的に調べることを禁止します。
したがって、クラス外のイベントにサブスクライブされているものを見つけることは、せいぜい「回避策」です。
イベントを含むクラスのソースにアクセスでき、イベントに接続されたデリゲートを追跡したい場合は、イベント定義にaddおよびremove キーワードを実装し、Dictionary でそれらを手動で追跡します。
私があなたを正しく理解していれば。このクラスは、SocketAsyncEventArgs を使用して説明する未知の myvm クラスをラップします。明らかに、SocketAsyncEventArgs クラスのソース コードはありません。
そして、SocketAsyncEventArgs クラスの Completed イベントをラップしました。そのイベントがトリガーされると、_instance_Completed が発生し、次に _myvm イベントが発生します。したがって、_myvm イベントを購読/購読解除する必要があります。
次に、_myvm イベントをサブスクライブ/サブスクライブ解除するためのイベントを残します。サブスクライブ/サブスクライブ解除すると、デリゲートがリストに格納されるため、ClearEvents() メソッドを呼び出してクリアできます。
それが役立つことを願っています。
public class WrapperClass
{
private EventHandler<SocketAsyncEventArgs> _myEvent;
private SocketAsyncEventArgs _myvm;
private List<Delegate> delegates;
public WrapperClass()
{
delegates = new List<Delegate>();
}
public void SetInstance(SocketAsyncEventArgs myvm)
{
_myvm = myvm;
_myvm.Completed += new EventHandler<SocketAsyncEventArgs>(_instance_Completed);
}
private void _instance_Completed(object sender, SocketAsyncEventArgs e)
{
if (_myEvent != null)
{
_myEvent(sender, e);
}
}
public event EventHandler<SocketAsyncEventArgs> myEvent
{
add
{
delegates.Add(value);
_myEvent = (EventHandler<SocketAsyncEventArgs>)Delegate.Combine(_myEvent, value);
}
remove
{
delegates.Remove(value);
_myEvent = (EventHandler<SocketAsyncEventArgs>)Delegate.Remove(_myEvent, value);
}
}
public void ClearEvents()
{
foreach (var d in delegates)
{
_myEvent = (EventHandler<SocketAsyncEventArgs>)Delegate.Remove(_myEvent, d);
}
}
}