2

私はこれについてすべて間違っているかもしれませんが、私は立ち往生しています。サーバーから大量のデータをダウンロードする別のスレッドを生成する GUI アプリケーションがあります。このダウンロード スレッドが終了したら、メイン スレッドにシグナルを送信して、ダウンロードしたデータを表示できるようにします。

(メイン フォームから) Invoke を呼び出してデリゲートを呼び出して表示作業を実行しようとしましたが、これによりダウンローダー スレッドが完了するまでブロックされます。EndInvokeなしでBeginInvokeを実行したいのですが、そうするのは適切ではないことはわかっています。

4

2 に答える 2

7

いくつかのオプションがあります。

私の個人的なお気に入りは、TPL を使用することです。TaskFactoryUI スレッドでは、次のようにを作成できます。

// Given:
// TaskFactory uiFactory;

uiFactory = new TaskFactory(TaskScheduler.FromCurrentSynchronizationContext());

Task次に、バックグラウンド タスクで、 UI を更新する を作成するだけです。

var task = uiFactory.StartNew( () => UpdateUserInterface(data));

これにより、呼び出しと同様に、UI スレッドに正しくマーシャリングされBeginInvokeます。ブロックする必要がある場合は、呼び出すことができますtask.Wait()(またはtask.ResultUpdate メソッドが値を返す場合)。

于 2013-01-02T21:13:23.803 に答える
0

いくつかのオプションがあります:

  • WinForms の場合、Control.BeginInvoke メソッドを使用します。
  • WPF の場合、Dispatcher.BeginInvoke メソッドを使用します。
  • 「TPL には、デフォルトのスケジューラーに加えて他のスケジューラーがあり、カスタム スケジューラーを作成することもできます。TPL が提供するスケジューラーの 1 つは、現在の同期コンテキストに基づいており、私のタスクが UI で確実に実行されるようにするために使用できます。スレッド。" (ソース記事):

    var ui = TaskScheduler.FromCurrentSynchronizationContext();
    Task.Factory.ContinueWhenAll(tasks.ToArray(),
        result =>
        {
            var time = watch.ElapsedMilliseconds;
            label1.Content += time.ToString();
        }, CancellationToken.None, TaskContinuationOptions.None, ui);
    

    ダウンロード シナリオの場合、.ContinueWith()続行が適切です。

于 2013-01-02T21:17:56.177 に答える