タスク並列ライブラリはまだベータ版であり、利用できるリソースが少なくなる可能性が高いことを知っていますが、私が読んだものから、ライブラリはタスクのスケジューリング、例外処理、キャンセルに非常に特別な扱いをします。
しかし、進捗状況の報告とタスクからの増分結果の送信への参照は見つかりません。これらの2つのことは無視できないほど重要に思えます。タスク並列ライブラリでこれらを処理する方法に光を当てたり、それらを説明するいくつかの記事を参照したりできますか?
タスク並列ライブラリはまだベータ版であり、利用できるリソースが少なくなる可能性が高いことを知っていますが、私が読んだものから、ライブラリはタスクのスケジューリング、例外処理、キャンセルに非常に特別な扱いをします。
しかし、進捗状況の報告とタスクからの増分結果の送信への参照は見つかりません。これらの2つのことは無視できないほど重要に思えます。タスク並列ライブラリでこれらを処理する方法に光を当てたり、それらを説明するいくつかの記事を参照したりできますか?
この例では、進行状況バーを更新します。
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
class SimpleProgressBar : Form
{
[STAThread]
static void Main(string[] args)
{
Application.EnableVisualStyles();
Application.Run(new SimpleProgressBar());
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
int iterations = 100;
ProgressBar pb = new ProgressBar();
pb.Maximum = iterations;
pb.Dock = DockStyle.Fill;
Controls.Add(pb);
Task.ContinueWith(delegate
{
Parallel.For(0, iterations, i =>
{
Thread.SpinWait(50000000); // do work here
BeginInvoke((Action)delegate { pb.Value++; });
});
});
}
}
これは私のトップの検索結果の 1 つであり、Task Parallel Library
ここでの進歩の例はまだありません...
今日、新しいマルチスレッドアプリケーションを開発したいのですが、使用せずにTPLに出くわしましたBackgroundWorker
(前に素敵なコードでタスクについてどこかで読んだため)
@Stephen Clearyの回答、進行状況を探すのが非常に複雑な彼のリンク、および他のいくつかのWebサイトの例をコンパイルします。
これは、 UI スレッド セーフな方法でProgressとCompletedを実行する方法の非常に簡単な例です。
TaskScheduler currentTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
Task<string>.Factory.StartNew(() =>
{
// loop for about 10s with 10ms step
for (int i = 0; i < 1000; i++)
{
Thread.Sleep(10);
Task.Factory.StartNew(() =>
{
// this is a task created each time you want to update to the UI thread.
this.Text = i.ToString();
}, CancellationToken.None, TaskCreationOptions.None, currentTaskScheduler);
}
return "Finished!";
})
.ContinueWith(t =>
{
// this is a new task will be run after the main task complete!
this.Text += " " + t.Result;
}, currentTaskScheduler);
コードは 10 秒以内に 1 から 1000 を表示し、「Finish!」を追加します。Windows フォームのタイトル バーの文字列。タスクはメイン スレッドで実行されるようにスケジュールされていると思われるため、TaskScheduler は UI スレッド セーフな更新を作成するためのトリッキーな方法であることがわかります。
BackgroundWorkerのような組み込みのサポートはありません。
彼らはSynchronizationContextを直接使うことができます。ここに優れたビデオがあります: http ://www.rocksolidknowledge.com/ScreenCasts.mvc/Watch?video = TasksAndThreadAffinity.wmv
著者は、このビデオで2つのソリューションを開発しています。1つはSynchronizationContextを使用し、もう1つはタスク継続を使用します。問題の場合、継続は機能しませんが、SynchronizationContextアプローチは正常に機能します。
PS再利用可能なコードを作成している場合は、SynchronizationContext.Currentをキャプチャするときに、nullをテストし、(nullの場合は)代わりにデフォルトで構築されたSynchronizationContextを使用する必要があります。
更新:このためのコードをブログに投稿しました。私のソリューションは、実際には、下を使用するにTask
よってUIスレッドに戻されるようにスケジュールされているに基づいています。受け入れられた回答とは異なり、このソリューションはWPFフォームとWindowsフォームの両方で機能します。TaskScheduler
SynchronizationContext
TPL は特に UI サポートに向けられたものではありません。そのために BackgroundWorker を (まだ) 使用できます。中間結果の送信または処理に関しては、それをサポートする新しいコレクション クラス (ConcurrentQueue) があります。
非同期タスクからの進行状況を報告するには、IProgressを非同期メソッドに渡します。メソッド内で、進行状況データを使用してReportを呼び出します。呼び出し元は、その進行状況レポートの処理方法を決定できます (つまり、無視するか、UI を更新します)。