2013-04-09 21 views
3

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

我即将做的,而不是这是什么:

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

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

回答

0

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

通过Rx,您可以组合(多个事件源),限制用户输入,以便不会压倒源,并且最重要的是,如果用户在搜索框中键入更多内容,则可以忽略旧结果(TakeUntil)。

更多信息:

Rx: Curing your asynchronous programming blues

Curing the asynchronous blues with the Reactive Extensions for .NET

例子:

SO: RX AutoCompleteBox

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和使用代理Beginxx x Endxxx方法。

1

因此,基本上等待1秒让用户在请求结果前停止键入。

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

我的猜测是你的原始问题是这是一个winforms应用程序,并且你所做的请求是默认同步的。因此,当应用程序正在等待响应时,文本框不接受用户输入。只是让调用异步应该可以解决这个问题,而不会让输入变慢。

+0

我明白了。有没有任何选项可以使WCF调用异步? – David 2013-04-09 17:11:22

+0

这里有几个链接例子:http://stackoverflow.com/questions/781932/async-call-to-wcf-with-c – LouD 2013-04-09 18:13:32

+0

一些直接的WCF链接在这里:http://msdn.microsoft.com/ en-us/library/ms730059.aspx,http://code.msdn.microsoft.com/windowsdesktop/How-to-Implement-a-WCF-2090bec8 – LouD 2013-04-09 18:20:47