2

给定以下代码:

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
        });
    }
}

鉴于我希望订阅遵循 MainWindow 的生命周期,从 mouseMoveSubscription 中处理\取消订阅的正确\最佳位置在哪里。我主要担心的是我不会导致持续超过 Windows 生命周期的内存泄漏。谢谢。

4

3 回答 3

3

要使用 Rx 以更可组合的方式执行此操作,请考虑从上面提到的“CloseEvent”创建一个 Observable 流。

例如 var closingObservable = Observable.FromEventPattern(this.Closing... etc) 然后,修改您的查询以使用 TakeUntil: mouseMove.TakeUntil(closingObservable).Subscribe(args =>

然后,您不必担心自己的显式处置。

于 2013-02-11T09:55:43.960 回答
1

我认为从窗口生命周期的角度来看,最好的地方是Closing事件。

这是窗口关闭过程的开始(如此处或此处所示) - 我发现最好知道要卸载(或在这种情况下取​​消订阅)后立即卸载所有内容。如果您出于任何原因需要尽可能长时间地订阅,请使用Closedeven 代替。

于 2013-02-11T03:00:25.860 回答
1

我通常同意@Honza,这Closing是执行此操作的合适位置-但我通常遵循这种模式来“托管” IDisposables;它在某些地方可能有点矫枉过正,但我​​发现它是一个足够轻量级的模式,它通常适用:

// 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);
    }
}
于 2013-02-11T16:10:22.740 回答