Reactive Extensions,锁和线程

时间:2010-12-08 13:28:53

标签: c# multithreading system.reactive

我正在使用反应式扩展来使用wpf ui,基本上我有一个文本框,我需要在小时间盘(200-300)上进行采样和限制(在打字时不断做一些东西,在停止打字时做一些东西) MS)

问题在于它有点不可预测,有时会立即触发限制,这可能是因为TextUpdated事件没有使它成为observable或具有observable本身的东西。我也在做一些可能会干扰的锁定,但这通常是通过新的任务而不是在UI线程上完成的。我也有一种潜在的怀疑,调试可能会影响行为,因为当我设置断点时它似乎触发更多“错误”

由于observable是在UI线程上创建的,我假设(可能是错误的)它的计时器或其下面使用的任何东西也在该线程上,创建一个新线程来创建可观察对象可能是一个好主意所以它不会受到干扰通过UI开销和潜在锁定?我如何以最好的方式设置这样一个线程,我想在它结束时空的while循环可能不是一个好主意:)

与线程关系中的节流,示例工作和被动扩展如何在引擎盖下工作?

修改

似乎问题就在于我测试它的方式:P如果按住一个键,它似乎在开始重复之前有500毫秒的延迟,如果你只是按键就可以正常工作。叹息

1 个答案:

答案 0 :(得分:1)

SampleThrottle都使用Scheduler.ThreadPool作为他们的时间安排,所以我很怀疑这是问题所在。

我建议在代码中添加一些日志记录,以找出瓶颈所在:

sourceEvents.LogInterval("Source")
    .Throttle(throttleTimeSpan).LogInterval("Throttled")
    .Sample(sampleTimeSpan).LogInterval("Sample")
    .Subscribe();

以下是LogInterval的定义:

public static class ObservableEx
{
    public static IObservable<TSource> LogInterval(
        this IObservable<TSource> source, string message)
    {
        return source
            .TimeInterval()
            .Do(x => Debug.WriteLine("{0} :: {1} ({2})", 
                message, x.Value, x.Interval.TotalMilliseconds);
            .RemoveTimeInteval();
    }
}

如果瓶颈是油门/样品,则可能意味着您在其他地方使ThreadPool饱和。如果是这种情况,并且这些限制器的性能很重要,您可以考虑创建专用线程+调度程序并使用自定义DistpatcherScheduler作为限制器/样本。或者,可能有更好的TPL解决方法。