Исключение перекрестной нити с дросселем в реактивных расширениях - PullRequest
4 голосов
/ 14 января 2011

Я использую Reactive Extensions для проверки ввода текстового поля.Я пытаюсь использовать .Throttle (TimeSpan.FromMilliseconds (500)).

Но когда я добавляю метод .Throttle (), при обращении к объекту пользовательского интерфейса в .Subscribe () возникает исключение перекрестного потока.Метод.

Он работает на 100% без газа, почему он ломается?

Мой код:

 var textChangedEvent = Observable.FromEvent<TextChangedEventArgs>(usernameTextbox, "TextChanged")
                                    .Throttle(TimeSpan.FromMilliseconds(500))

        textChangedEvent.Subscribe(changed =>
            {
                TextBox oUsernameTextBox = changed.Sender as TextBox;

                //Accessing oUsernameTextBox throws Cross Thread Exception
            });

Спасибо, Оливер

Ответы [ 2 ]

4 голосов
/ 14 января 2011

По умолчанию Throttle использует ThreadpoolScheduler, поэтому события не будут поступать в поток пользовательского интерфейса.Поскольку вам нужны события в потоке пользовательского интерфейса, используйте: -

var textChangedEvent = Observable.FromEvent<TextChangedEventArgs>(usernameTextbox, "TextChanged")
        .Throttle(TimeSpan.FromMilliseconds(500), Scheduler.Dispatcher);

Это вернет события обратно в поток пользовательского интерфейса.

0 голосов
/ 26 апреля 2012

Мне пришлось немного подправить код, чтобы он работал в приложении LightSwitch (SilverLight 4) с Rx v1.0.10621 из-за некоторых изменений интерфейса в Rx с тех пор, как был задан этот вопрос.

Нужно установить Rx и ссылаться на сборки System.Reactive и System.Reactive.Windows.Threading (для LightSwitch эта ссылка находится в проекте Client).

Затем используйте этот код для регулирования TextChange событие в текстовом поле:

(Примечание: для светового переключателя этот код входит в обработчик ControlAvailable)

var textChangedEvent = Observable
                       .FromEventPattern<TextChangedEventArgs>(e.Control, "TextChanged")
                       .Throttle(TimeSpan.FromMilliseconds(500))
                       .ObserveOnDispatcher();

        textChangedEvent.Subscribe(changed =>
        {
            var tb = changed.Sender as TextBox;
            if (tb.Text.Length >= 3) // don't search for keywords shorter than 3 chars
            {
                // search
            }
        });
...