3

在 WPF 应用程序中,我Observable.Throttle()用来限制处理来自用户界面的某些事件的频率。

这是与 Rx 的使用有关的最小简化代码:

using System.Reactive.Linq;
using System.Reactive.Subjects;

public class UIEvent
{
    public UIEvent(string name)
    {
        this.Name = name;
    }

    public string Name { get; }
}

public class ViewModel
{
    private ISubject<UIEvent> subject = new Subject<UIEvent>();

    // IEventAggregator is from Caliburn.Micro, but that should not be relevant here.
    public ViewModel(IEventAggregator eventAggregator)
    {
        this.subject
            .Throttle(TimeSpan.FromMilliseconds(500))
            .Subscribe(eventAggregator.Publish);
    }

    // This is called from several places in the associated view
    public RaiseUiEvent(string name)
    {
        this.subject.OnNext(new UIEvent(name));
    }
}

这通常运作良好并解决了我们之前遇到的种族问题。但是,在某些时候,即使事件发生的频率很低,这也会锁定在subject.OnNext(). 此时在 Visual Studio 中暂停显示以下相关调用堆栈:

WindowsBase.dll!System.Windows.Threading.DispatcherSynchronizationContext.Wait(System.IntPtr[] waitHandles, bool waitAll, int millisecondsTimeout)
[Native to Managed Transition]      Annotated Frame
[Managed to Native Transition]      Annotated Frame
System.Reactive.Linq.dll!System.Reactive.Linq.ObservableImpl.Throttle<UIEVent>._.OnNext(UIEvent value)
ViewModel.RaiseUiEvent(string name)

我假设/希望根本原因是我对 Rx 的使用非常天真/缺乏经验。我尝试同步主题,我记得这帮助我解决了另一个地方的问题,但这并没有改变这里的行为。我也尝试过SubscribeOn()/ ObserveOn(),但没有真正的计划或运气。

我用错了主题吗?我应该使用不同的主题类型吗?我应该使用一个主题吗?(由于实际代码的复杂性,通过 Rx 直接附加到视图中的事件并合并流似乎不可行。)

感谢您的任何指点!

4

0 回答 0