3

我有一个“自动完成”文本框,每次按下一个键时都会调用一个 WCF 方法。反过来,WCF 服务器将运行 SQL 查询,返回前 15 个结果并发送它们。但是,这会导致在框中键入时出现明显的延迟。

我要做的是:

  • 当触发 text_changed 事件时创建一个新线程,使用 Stopwatch.ElapsedMilliseconds 使该线程等待 1000 毫秒。在这段等待时间内,线程可以永久停止。
  • 如果没有停止,线程会将请求发送到服务器(并重新填充自动完成框)。
  • 一旦触发了新的“text_changed”事件,我将停止当前线程并启动一个新线程。

有没有更好的方法或者这是要走的路?

4

2 回答 2

1

所以基本上在请求结果之前等待 1 秒让用户停止输入。

这是节省服务器资源的一个很好的解决方案,但您实际上是通过让用户等待至少 1000 毫秒来增加延迟。

我的猜测是,您最初的问题是这是一个 winforms 应用程序,并且您发出的请求默认是同步的。结果,当应用程序等待响应时,文本框不接受用户输入。只需使调用异步就可以解决该问题,而不会使输入速度变慢。

于 2013-04-09T17:10:04.123 回答
0

另一种方法是使用 Rx (Reactive Extensions) 框架来封装具有一些非常有趣的特性的 automplete。

使用 Rx,您可以编写(多个事件源),限制用户输入,以免淹没源,此外,如果用户在搜索框中键入更多内容(TakeUntil),您可以忽略旧结果。

更多信息:

Rx:治愈你的异步编程忧郁症

使用 Reactive Extensions for .NET 治愈异步忧郁症

例子:

SO:RX 自动完成框

RxProperty = Observable.FromEvent<TextChangedEventHandler, TextChangedEventArgs>(
        h => new TextChangedEventHandler(h),
        h => AssociatedObject.TextChanged += h,
        h => AssociatedObject.TextChanged -= h)

        .Select(t => ((TextBox)t.Sender).Text)

        .Throttle(TimeSpan.FromMilliseconds(400))

        .SubscribeOnDispatcher()
        .Take(10)
        .TakeUntil(AssociatedObject.TextChanged );

代替 FromEvent,您可以使用 FromAsync 并使用代理 Beginxxx Endxxx 方法。

于 2013-04-09T19:05:58.457 回答