1

すべて、Taskバックグラウンド スレッドで実行され、重い作業を行う があります。私が設定した方法は、これが行われている間、UI スレッドが進行状況情報で GUI を更新することです。その一部はアニメーション化された .gif ファイルを使用します。問題を説明するために、次のサンプル コードを見てください。

TaskScheduler uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
Task<bool> task = Task.Factory.StartNew(() => 
{
    // Heavy work.
    if (heavyWorkCompleted)
        MethodToUpdateGui(uiScheduler); // Update DataGridView ImageCell on UI thread
    // More work.
}

「重作業」の実行中に適切な DGV 画像セルに表示される「進行中」の画像があります。「重作業」が成功した場合、この画像は (DGV1 で) ティックに変化し、これをMethodToUpdateGui(uiScheduler)使用します (変更されたばかり) 。 DGV2 を更新するための DGV1 のイメージ。ただし、MethodToUpdateGui(uiScheduler)実行時に DataGridView (DGV2) の更新が速すぎることがあります。これが意味することは、画像が私が望む目盛りではないということです(そして、それは正常な完了によるものでなければなりません)それは「進行中」の画像です。DGV の更新速度が、私が行っていることに対して十分ではないようです。

これを行うより良い方法はありますか?GUI の更新後にバックグラウンド スレッドを回転させて、DGV1 が「追いつく」ことができるようにしますか [これは厄介です!]?

御時間ありがとうございます。

4

1 に答える 1

1

これを行うためのより良い方法はありますか?GUIの更新後にバックグラウンドスレッドをスピンして、DGV1が「追いつく」ことができるようにすることはできますか[これは厄介です!]?

ここでの問題は、TPLがSynchronizationContext.Postを使用してメッセージをUIスレッドに送信することです。メソッドが実行されると、タスクは非同期で実行され、GUIはすぐには更新されません。

GUIが更新されていることを確認したい場合、最も簡単なオプションは、をMethodToUpdateGui介してスケジュールされたタスクを待機することによってブロックを取得することですuiScheduler

これは次のようになります。

void MethodToUpdateGui(TaskScheduler uiScheduler)
{
    var updateTask = Task.Factory.StartNew( () =>
    {
        // update gui
    }, CancellationToken.None, TaskCreationOptions.None, uiScheduler);

    // Block until Task completes...
    updateTask.Wait();
}

これは、スピンを試みるよりも優れています。これは、ブロックされ、TPLによって自動的に通知されるためです。

これは、Windowsフォームの用語では、Control.Invoke代わりに効果的に実行されます。Control.BeginInvoke

于 2012-05-22T17:50:43.667 に答える