Reputation: 3657
Given the following code:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var mouseMove = Observable
.FromEventPattern<MouseEventHandler, MouseEventArgs>(
eventHandler => this.MouseMove += eventHandler,
eventHandler => this.MouseMove -= eventHandler);
var mouseMoveSubscription = mouseMove.Subscribe(args =>
{
//Do Something
});
}
}
Where is the correct\best place to dispose\unsubscribe from mouseMoveSubscription given I want the subscription to follow the MainWindow's lifetime. My main concern is I don't cause a memory leak that lasts past the windows lifetime. Thanks.
Upvotes: 2
Views: 492
Reputation: 16904
I generally agree with @Honza that Closing
is the appropriate place to do this - but I follow this pattern generally for "hosted" IDisposables
; it might be a touch overkill in places, but I find it to be a lightweight-enough pattern that it is generally applicable:
// Window, application, etc - some longish-living object
public class Something : IDisposable
{
CompositeDisposable _disposables = new CompositeDisposable();
public Something()
{
// A composite disposable acts like a "bucket" of IDisposables
// that are all disposed when the bucket is disposed.
_disposables.Add(SomeObservable.Subscribe(...));
_disposables.Add(SomeOtherObservable.Subscribe(...));
_disposables.Add(YetAnotherObservable.Subscribe(...));
// Here, optionally wire some "Yo, I should dispose when this happens" handler
this.Closed += (o,e) => Dispose();
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// clean up managed resources here
if(_disposables != null)
{
_disposables.Dispose();
}
}
// clean up unmanaged resources here
}
~Something()
{
Dispose(false);
}
}
Upvotes: 1
Reputation: 179
To do this in a more composable way with Rx, consider creating an Observable stream from the 'CloseEvent' the people above have already mentioned.
e.g. var closingObservable = Observable.FromEventPattern(this.Closing... etc) Then, amend your query to use TakeUntil: mouseMove.TakeUntil(closingObservable).Subscribe(args =>
You then needn't concern yourselve with explicit disposal.
Upvotes: 3
Reputation: 10947
I think the best place from the window lifetime point of view is the Closing
event.
It is the beginning of the window's shutdown process (as shown here or here) - I find it better to unload everything as soon as I know it is to be unloaded (or unsubscribed in this case). If you need to keep subscribed as long as possible for any reason, use the Closed
even instead.
Upvotes: 1