Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/264.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WPF:如何在具有延迟时间的单独线程中调用方法_C#_Wpf_Multithreading_C# 4.0_Dispatcher - Fatal编程技术网

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

C# WPF:如何在具有延迟时间的单独线程中调用方法,c#,wpf,multithreading,c#-4.0,dispatcher,C#,Wpf,Multithreading,C# 4.0,Dispatcher,我有一个文本框,用户可以在其中输入搜索词。它绑定到my视图模型中的字符串项属性。我想在内容发生变化时进行搜索查询。但是我想在一个单独的线程中使用延迟进行查询 e、 g.当用户键入字母时,我想等待0.3秒,如果用户在此时间(0.3秒)内更改输入,计时器将重置并再次启动。否则,我将启动一个新线程并执行搜索查询。在执行查询时,如果用户再次更改术语,则中止prev查询并重新启动 我知道如何在windows窗体中使用线程和Timer类实现这一点。但是我对WPF是新手,我正在搜索是否有一种方法可以指定WPF

我有一个
文本框
,用户可以在其中输入搜索词。它绑定到my
视图模型中的
字符串项
属性。我想在内容发生变化时进行搜索查询。但是我想在一个单独的线程中使用延迟进行查询

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

我知道如何在windows窗体中使用线程和
Timer
类实现这一点。但是我对
WPF
是新手,我正在搜索是否有一种方法可以指定WPF线程功能(或者可能是一种性能更好的方法)


你知道吗?您能帮我吗?

您可能需要查看Microsoft提供的。一旦某个延迟过去,Rx提供了一种将这些类型的事件聚合为单个事件的方法

Phil Haack(前微软公司)在他的博客上发表了一篇很好的文章,他谈到了节流功能。

你可以使用。在每次按键时,如果计时器已经运行,则停止计时器,然后启动计时器。我相信(你应该检查一下!)这将重置它

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


基本上,这将“新线程”部分与“我真的想做些什么”部分分开,将UI线程上的所有内容保留到您决定确实想做些什么(并且您知道您想要使用的价值)的时候。

这只是建立在Jon Skeets所说的基础上。给他打勾。出现
.stop()
以重置
计时器

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);
    }
}

你是乔恩·斯基特,我不明白你在说什么!!!:D我对WPF是个新手,现在我只有187分。您的解决方案似乎比Robaticus的好,但我需要一些代码来理解它:D我在想,我应该有一个线程(而不是在每个查询上都有一个新线程,这似乎是一个更好的性能),然后运行或中止它。这是真的吗?我也很高兴与你交谈。非常感谢。@king.net:您不想中止线程,但是如果输入发生更改,您可以忽略结果。阅读
dispatchermer
了解这部分内容,然后分别处理线程问题。好的,你说得对。我读了>我明白你刚才在说什么。但在开始编码之前,只有一个问题:我可以从它的
回调中停止
Dispatchermer
?@king.net:停止进一步的“滴答声”吗?绝对。@king.net:发出查询后,您根本不需要计时器(除非用户键入其他字符)。但是您通常不会中止查询-您只需忽略结果。当然,如果您的查询确实支持取消,那就太好了-但是我们需要了解更多关于搜索的信息,以了解如何在这方面帮助您。正如John所说,如果我们有一个支持取消的查询,
BackgroundWorker
似乎是不必要的。不过,谢谢你,在我的情况下,这不是一个问题。我做第一部分。但还有另一个问题。请看一下完成情况: