4

TextBoxユーザーが検索語を入力できるようにしています。string Termmy のプロパティにバインドしますview-model。そして、内容が変更されたときに検索クエリを実行したいと考えています。しかし、別のスレッドでクエリを実行したいのですが、遅延があります。

たとえば、ユーザーが文字を入力したときに0.3 秒待ちたいのですが、ユーザーがこの時間 (0.3 秒) 以内に入力を変更すると、タイマーがリセットされ、再び開始されます。それ以外の場合は、新しいスレッドを開始して検索クエリを実行します。クエリの実行中にユーザーが用語を再度変更した場合は、前のクエリを中止し、最初からやり直してください。

私は、スレッドとTimerクラスを使用して Windows フォームでこれを行う方法を知っています。しかし、私は初めてでWPF、WPFスレッド機能に指定された方法があるかどうかを探しています(または、パフォーマンスが向上する方法である可能性があります)。

何か考えはありますか?手伝って頂けますか?

4

3 に答える 3

2

を使用できますDispatcherTimer。キーを押すたびに、タイマーが既に実行されている場合は停止してから開始します。私はそれがリセットされると信じています(これを確認する必要があります!)。

起動した場合は、テキスト ボックスの現在の値を取得し、別のスレッドで操作の実行を開始します (たとえばTask.Factory.StartNew、.NET 4 を使用している場合は を使用するかBackgroundWorker、新しいスレッドを作成するだけです)。

基本的に、これは「新しいスレッド」の部分を「本当にやりたいこと」の部分から分離し、何かを本当にやりたいと判断した時点まですべてを UI スレッドに保持します (そして、その値を知っています)。使いたい)。

于 2012-05-09T20:36:38.777 に答える
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);
    }
}
于 2012-05-10T00:05:26.543 に答える
0

Microsoft のReactive Extensionsを調べることをお勧めします。Rx は、特定の遅延が経過すると、これらのタイプのイベントを 1 つのイベントに集約する方法を提供します。

Phil Haack (元 Microsoft) は、彼のブログに優れた記事を掲載しており、スロットリング機能について語っています。

于 2012-05-09T20:36:32.160 に答える