.NET 4.0「タスク並列ライブラリ」での進捗レポートと増分結果のサポート
-
20-09-2019 - |
質問
私はそれを知っています タスク並列ライブラリ まだベータ版であり、利用できるリソースは少ないと思われますが、私が読んだ限りでは、ライブラリは非常に特別な扱いをしています タスクのスケジュール設定, 例外処理 そして キャンセル.
しかし、何も参考になりません 進捗報告 そして 増分結果の送信 タスクから。これら 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++; });
});
});
}
}
他のヒント
このは右ここに私のトップの検索結果とTask Parallel Library
の進歩のためにまだ例の一つである...
私は新しいマルチスレッド・アプリケーションを開発したいので、私はちょうどTPLに出くわした今日が、(私が前に素敵なコードを持つタスクについてどこかで読んので)BackgroundWorker
を使用しない
私は@Stephenクリアリーの答えは、進捗を探すためにはかなり複雑な彼のリンク、およびいくつかの他のウェブサイトからの例をコンパイルします。
これが行う方法に非常に単純な例ではあるの進捗状況と UIスレッドセーフな方法で完了の
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秒以内に1000に1を表示し、追加します「完了を!」 Windowsフォームのタイトルバーの文字列。あなたはTaskSchedulerは、私がスケジュールされたタスクは、メインスレッド上で実行されると思うので、UIスレッド安全なアップデートを作成するトリッキーな方法であることが確認できます。
BackgroundWorker にあったような、これに対するサポートは組み込まれていません。
SynchronizationContext を直接使用できます。ここに素晴らしいビデオがあります: http://www.rocksolidknowledge.com/ScreenCasts.mvc/Watch?video=TasksAndThreadAffinity.wmv
このビデオでは、著者が 2 つのソリューションを開発しています。1 つは SynchronizationContext を使用し、もう 1 つはタスク継続を使用します。あなたの問題では、継続は機能しませんが、SynchronizationContext アプローチは正常に機能します。
追伸再利用可能なコードを作成している場合は、SynchronizationContext.Current をキャプチャするときに、null かどうかをテストし、(null の場合は) 代わりにデフォルトで構築された SynchronizationContext を使用する必要があります。
アップデート:このコードを投稿しました 私のブログで. 。私の解決策は実際に基づいています Task
これは、UI スレッドに戻されるようにスケジュールされます。 TaskScheduler
を使用する SynchronizationContext
その下に。受け入れられた回答とは異なり、この解決策は WPF と Windows フォームの両方で機能します。
TPLは、特にUIのサポートを指向されていない、あなたは(まだ)そのためのBackgroundWorkerを使用することができます。中間結果を送信または処理するように、それをサポートするための新しいcollectionclasses(ConcurrentQueue)があります。
<のhref = "http://msdn.microsoft.com/en-us/library/hh138298%28v=vs.110%29.aspx" のrel = "nofollowのを渡し、非同期タスクから進捗状況を報告するには「> IProgress の非同期メソッドに。メソッド内で、レポートがでを呼び出します進捗データ。呼び出し側は(すなわち、それを無視するか、UIを更新)その進捗報告書をどのように処理するかを決めることができます。