WPF:如何在具有延迟时间的单独线程中调用方法

时间:2012-05-09 20:32:33

标签: c# wpf multithreading c#-4.0 dispatcher

我有TextBox用户可以在其中输入搜索字词。它绑定到string Term中的view-model属性。我希望在内容发生变化时进行搜索查询。但我想在一个单独的线程中使用延迟进行查询。

e.g。当用户键入字母时,我想等待 0.3秒,如果用户在此时间内(0.3秒)更改输入,则计时器重新启动并再次启动。否则,我启动一个新线程并执行搜索查询。当查询正在执行时,如果用户再次更改术语,则中止prev查询并重新开始。

我知道如何在带有线程和Timer类的windows表单中执行此操作。但我是WPF的新手,我正在寻找是否有为WPF线程功能指定的方法(或者可能是一种性能更好的方式)。

你有什么想法吗?你能救我吗?

3 个答案:

答案 0 :(得分:2)

您可以使用DispatcherTimer。在每个按键上,如果计时器已经运行,请将其停止,然后启动它。我相信(你应该检查一下!)那会重置它。

如果它触发,则接受文本框中的当前值并开始在单独的线程中执行操作(例如,使用Task.Factory.StartNew,如果您使用的是.NET 4,或BackgroundWorker,或者只是创建一个新线程。)

基本上将“新线程”部分与“我真的想要做某事”部分分开,将所有内容保留在UI线程上,直到您确定 想要想要做某事(你知道你想要使用的价值)。

答案 1 :(得分:0)

您可能希望查看Microsoft的Reactive Extensions。一旦某个延迟过去,Rx提供了将这些类型的事件聚合到单个事件中的方法。

Phil Haack(前身为微软)在blog上发表了一篇很好的文章,他谈到了节流能力。

答案 2 :(得分:0)

这只是建立在Jon Skeets所说的基础之上。给他一个复选标记。 .stop()似乎重置了timer

public MainWindow()
{
    InitializeComponent();

    backgroundWorker1 = new BackgroundWorker();
    backgroundWorker1.WorkerReportsProgress = true;
    backgroundWorker1.WorkerSupportsCancellation = true;
    backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
    backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
    backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);

    dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
    dispatcherTimer.Interval = new TimeSpan(0, 0, 4);
}

public string Input
{
    get { return input; }
    set
    {
        if (value == input) return;
        value = value.Trim();
        input = value;
        NotifyPropertyChanged("Input");

        if (backgroundWorker1.IsBusy) backgroundWorker1.CancelAsync();
        dispatcherTimer.Stop();                
        dispatcherTimer.Start();
    }
 }

private void dispatcherTimer_Tick(object sender, EventArgs e)
{
    dispatcherTimer.Stop();
    if (!backgroundWorker1.IsBusy)
    {
        backgroundWorker1.RunWorkerAsync(Input);
    }
}