2011-12-16 1 views
4

私は、LINQクエリをプリコンパイルし、後で必要となるいくつかの値をプリコンパイルするためにいくつかのバックグラウンドスレッドを使用するWPFアプリケーションを持っています。 TPLがでこれらの作業を開始するために使用されます。この作品多くのTPLバックグラウンドスレッドは、WPFのUIスレッドで遅れを生みます。

var newTask = new Task(taskAction, myCancelToken, TaskCreationOptions.LongRunning); 
newTask.Start(); 

、タスクはしかし、これらのスレッドが高いCPU負荷を引き起こし、それがつまずくする傾向UIに知覚され、複数のCPUコアなどに分布していますスレッドが終了しない限り、フリーズすることもできます。

だから、UIをスムーズにするにはどうすればよいでしょうか。私が研究したことで、スレッドに特別な優先順位を与えるはずのものではないことがわかりました。他のものは、Thread.Sleep()を頻繁に使用することがやり方であることを意味しています。

私が気付いていない他の方法はありますか?スレッドの優先順位付けには本当に不利な点があります(これはTPL経由では直接実行できません)。

ありがとうございます!

タスクの優先順位付けに関する
+1

'TaskCreationOptions.LongRunning'は、スレッドプールを使用する代わりに新しいスレッドを作成します。いくつのスレッドが起動していて、ターゲットマシンにはいくつのコアがありますか? –

+0

私は約10個または12個のタスクを開始しています。 LongRunningモードはちょうど試したもので、私はそれがなくても同じ結果を出しました。特別な専用ターゲットシステムの設定がないため、コアの数が異なる場合があります。 –

答えて

0

10のスレッドを推奨されていない4コアマシンと言うにあまりにも多くのです。それらがプレコンパイルクエリのように計算上の制約を受けている場合、それらはすべてCPU時間に競合し、マシン全体が応答しなくなります。

Environment.ProcessorCountを使用して、使用可能なコアの数を調べ、一度に1つのスレッド(その数 - 1)だけを開始することをお勧めします。最初に実行される作業の優先順位付けを行い、他の作業を継続としてキューに入れることができます。

これは、あなたのUIスレッドをサービスするコアを自由にして、アプリケーションを再び応答させる必要があります。

+1

しかし、TPLは、CPUの数やコアの数など、システムのセットアップとパフォーマンスに応じて計算された多数のスレッドにタスクを配布するように設計されていませんか?そのため、私は〜12のタスクではなく、12のワーカースレッドを開始することを意味しました。その間、私はTaskCreationOptions.LongRunningを削除しましたが、私が言ったように、これは効果がありませんでした。 –

+1

'LongRunning'を指定すると、新しいスレッドが必要で、すぐに実行したいと言っています。通常のタスクを使用する場合、スレッドプールスレッドの注入/廃棄アルゴリズムの対象となりますが、それには独自のアイデアがありますが、常にマシン全体を使用しようとします。 1つのコアを常に空きのままにしておくことをお勧めします。手動でスケジュールする必要があります。 –

+0

これは、同時スレッドの数をProcessorCount - 1に制限するカスタムTaskSchedulerを作成することにつながります。 –

1

、あなたが http://blogs.microsoft.co.il/blogs/bnaya/archive/2011/01/29/how-to-schedule-task-on-different-thread-priority.aspx

のようになめらかに行うことができます。しかし、スレッドの優先順位の私の知る限り明示的な変更が実際

+1

私はスレッドの優先度の変更についてはお勧めしませんが読んだ。しかし、なぜそれは実際に可能なのですか?つまり、それは、バックグラウンドの作業が多い場合は、パフォーマンスの低いUIを使用して生きなければならないということです。 –

関連する問題