'Unsubscribing from event when object is disposed
What I'm trying to figure out is how to declaratively avoid the Object reference not set to an instance of an object
exception thrown when disposing of subscription to FromEventPattern
observable when the observed object gets disposed of before disposing of the subscription.
Here's a simplified example:
void Main()
{
EventSource oEventSource = new();
var source = Observable.FromEventPattern<MyEventArgs>(
h => oEventSource.MyEvent += h,
h => {
//if (oEventSource != null)
oEventSource.MyEvent -= h; // <--- error thrown here
})
.Select(x => x.EventArgs.Value)
.Subscribe(x => Console.WriteLine(x));
Observable.Interval(TimeSpan.FromMilliseconds(500)).Subscribe(x =>
{
oEventSource?.RaiseMyEvent(x);
});
Thread.Sleep(3000);
oEventSource = null;
Thread.Sleep(2000);
source.Dispose(); // <--- error thrown when disposing subscription
}
public class EventSource
{
public event EventHandler<MyEventArgs> MyEvent;
public void RaiseMyEvent(long x){
MyEvent?.Invoke(this, new MyEventArgs(x));
}
}
public class MyEventArgs : EventArgs
{
public MyEventArgs(long x) { Value = x;}
public long Value { get; set; }
}
I cannot make sure the subscription is disposed of before disposing of the "EventSource" object because the object is defined in viewModel and it is bound to the View where the subscription takes place.
Checking if EventSource object exists before removing the handler stops the error being raised (if (oEventSource != null)
), but won't it introduce a memory leak since the handler is never removed?
Solution 1:[1]
there is much confusion to your logic and your style is not really using RX e.g sequence composability. However an answer to your question is simply unsubscribe your source uppon the condition you want
.Select(x => x.EventArgs.Value)
.TakeUntil(l => oEventSource!=null) //this line
.Subscribe(x => Console.WriteLine(x));
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Apostolis Bekiaris |