2011-01-14 47 views
4

我正在使用Reactive Extensions來驗證文本框輸入。 我正在嘗試使用.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 
      }); 

感謝 -Oliver

回答

4

默認Throttle使用ThreadpoolScheduler這樣的事件不會對UI線程到達。由於您需要在UI線程上使用以下事件: -

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

這會將事件重新放回到UI線程上。

+0

+1有任何操作一個`IScheduler`重載不能被信任在與調用者相同的線程上運行。這也是最好使用`IScheduler`過載,而不是使用`ObserveOn` – 2011-01-14 13:23:58

0

我不得不調整一下代碼,使其在其中Rx v1.0.10621一個LightSwitch的(Silverlight 4中)應用工作,由於從何時起已經問過這個問題在一定的Rx界面的變化。

需要install Rx並參考System.ReactiveSystem.Reactive.Windows.Threading程序集(LightSwitch此參考去Client項目)。

然後使用此代碼文本框油門的TextChange事件:

(注:LightSwitch的這一代碼進入在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 
      } 
     });