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
似乎是不必要的。不过,谢谢你,在我的情况下,这不是一个问题。我做第一部分。但还有另一个问题。请看一下完成情况: