使用Rx将受限制的TextBox.TextChanged与TextBox.GotFocus/(延迟)LostFocus联

本文关键字:TextBox 延迟 LostFocus GotFocus Rx 受限制 TextChanged 使用 | 更新日期: 2023-09-27 18:19:37

我正在使用Rx为WPF中的TextBoxes创建某种"ProbablyDoneTyping"。

我通过加入GotFocus的Observable和像这样的TextChanged的Observables来完成所有工作

var gotFocus = Observable.FromEventPattern<RoutedEventArgs>(textBox, "GotFocus");
var delayedLostFocus = Observable.FromEventPattern<RoutedEventArgs>(textBox, "LostFocus")
    .Delay(TimeSpan.FromMilliseconds(850));
var throttledTextChanged = Observable.FromEventPattern<TextChangedEventArgs>(textBox, "TextChanged")
    .Select(pattern => textBox.Text).Throttle(TimeSpan.FromMilliseconds(750)).DistinctUntilChanged();
var immediately = Observable.Empty<Unit>();
var probablyDoneTyping = gotFocus.Join(throttledTextChanged, _ => delayedLostFocus, _ => immediately, (_, text) => text);
probablyDoneTyping.ObserveOn(SynchronizationContext.Current).Subscribe(text => Title = text);

我在LostFocus上引入了延迟,这样我就可以离开TextBox,并且可能的DoneTyping仍然会启动。

但这给了我一个System.OperationCanceledException,每当我离开textBox时,它都会在Delay中产生。

异常的堆栈跟踪是

System.Reactive.Linq.dll!System.Reactive.Linq.ObservableImpl.Delay<System.Reactive.EventPattern<System.Windows.RoutedEventArgs>>.LongRunningImpl.DrainQueue Normal
mscorlib.dll!System.Threading.CancellationToken.ThrowOperationCanceledException()    
mscorlib.dll!System.Threading.SemaphoreSlim.Wait(int millisecondsTimeout, System.Threading.CancellationToken cancellationToken)  
mscorlib.dll!System.Threading.SemaphoreSlim.Wait(System.Threading.CancellationToken cancellationToken)   
System.Reactive.Linq.dll!System.Reactive.Linq.ObservableImpl.Delay<System.Reactive.EventPattern<System.Windows.RoutedEventArgs>>.LongRunningImpl.DrainQueue(System.Reactive.Disposables.ICancelable cancel)  
System.Reactive.Core.dll!System.Reactive.Concurrency.Scheduler.ScheduleLongRunning.AnonymousMethod__72(System.Action<System.Reactive.Disposables.ICancelable> a, System.Reactive.Disposables.ICancelable c)  
System.Reactive.Core.dll!System.Reactive.Concurrency.DefaultScheduler.LongRunning.ScheduleLongRunning<System.Action<System.Reactive.Disposables.ICancelable>>.AnonymousMethod__b(object arg)     
System.Reactive.PlatformServices.dll!System.Reactive.Concurrency.ConcurrencyAbstractionLayerImpl.StartThread.AnonymousMethod__4()    
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object state)     
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)    
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)    
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state)  
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart()     

该异常不会影响我的应用程序,但它会被抛出,如果我突破公共语言运行时异常,则每次离开TextBox时应用程序都会停止。我不想要这个。

为什么会抛出异常,我该如何处理它?

使用Rx将受限制的TextBox.TextChanged与TextBox.GotFocus/(延迟)LostFocus联

启用"仅我的代码"或禁用首次出现异常时的中断(尽管我不建议后者)。