反应式扩展中带有节流阀的跨线程异常

发布于 2024-10-12 04:37:59 字数 648 浏览 4 评论 0原文

我正在使用反应式扩展来验证文本框输入。 我正在尝试使用 .Throttle(TimeSpan.FromMilliseconds(500))。

但是,当我添加 .Throttle() 方法时,在 .Subscribe() 方法中访问 UI 对象时会引发跨线程异常。

没有节流阀的情况下它可以 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
            });

谢谢 -奥利弗

I am using Reactive Extensions to verification of a textbox input.
I am trying to use the .Throttle(TimeSpan.FromMilliseconds(500)).

But when I add the .Throttle() method a cross thread exception is thrown when accessing a UI object in the .Subscribe() method.

It works 100% without the Throttle, why is it breaking?

My code:

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

Thanks
-Oliver

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

踏月而来 2024-10-19 04:37:59

默认情况下,Throttle 使用ThreadpoolScheduler,因此事件不会到达 UI 线程。由于您需要 UI 线程上的事件,请使用:-

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

这会将事件放回到 UI 线程上。

By default Throttle uses the ThreadpoolScheduler so events will not arrive on the UI Thread. Since you need the events on the UI thread use:-

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

This will put the events back on the UI Thread.

爱冒险 2024-10-19 04:37:59

由于自从提出这个问题以来,Rx 中的一些界面发生了变化,我不得不对代码进行一些调整,使其在具有 Rx v1.0.10621 的 LightSwitch (SilverLight 4) 应用程序中工作。

需要安装Rx并引用System.ReactiveSystem.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
            }
        });

I had to tweak the code a bit to make it work in a LightSwitch (SilverLight 4) application with Rx v1.0.10621 due to some interface changes in Rx since when this question had been asked.

Need to install Rx and to reference System.Reactive and System.Reactive.Windows.Threading assemblies (for LightSwitch this reference go in the Client project).

Then use this code to throttle a the TextChange event on the text box:

(Note: For lightswitch this code goes in the ControlAvailable handler)

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
            }
        });
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文