何时使用WPF中的Rx处理鼠标事件

本文关键字:处理 鼠标 事件 Rx 中的 WPF 何时使 | 更新日期: 2023-09-27 17:58:31

给定以下代码:

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使用寿命的内存泄漏。谢谢

何时使用WPF中的Rx处理鼠标事件

要用Rx以更可组合的方式实现这一点,请考虑从上面提到的"CloseEvent"创建一个Observable流。

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

那么你就不必关心你自己的明确处置。

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

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

我通常同意@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);
    }
}