WPF: how to invoke a method in a separate thread with a delay time

我的梦境 提交于 2019-12-05 17:35:34

You could use DispatcherTimer. On each keypress, stop the timer if it's already running, then start it. I believe (and you should check this!) that that will reset it.

If it fires, you then take the current value in the textbox and start performing the operation in a separate thread (e.g. using Task.Factory.StartNew, if you're using .NET 4, or BackgroundWorker, or just creating a new thread).

Basically that separates the "new thread" part from the "do I really want to do something" part, keeping everything on the UI thread until the point where you've decided you really do want to do something (and you know the value you want to use).

You might want to look into the Reactive Extensions from Microsoft. Rx provides a way to aggregate these types of events into a single event, once a certain delay has passed.

Phil Haack (formerly of Microsoft) had a good article on his blog where he talks about the throttling capability.

paparazzo

This just builds on what Jon Skeets said. Give the check mark to him. The .stop() appears to reset the 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);
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!