タスクからの結果取得について。
タスクから結果を取得するにはタスク生成時にFuncオブジェクトを指定します。 その後、実行してResultプロパティを参照すれば結果が取得できます。
非同期処理なので、当然まだ処理が完了していない場合があります。 その場合、Resultプロパティは結果が取得できるまでブロックされます。
注意点として、非同期処理中に例外が発生していた場合 Resultプロパティにアクセスした時点で例外(AggregateExcepiton)が発生します。
以下、サンプルです。
namespace Sazare.Samples { using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using Sazare.Common; /// <summary> /// タスク並列ライブラリについてのサンプルです。 /// </summary> /// <remarks> /// タスク並列ライブラリは、.NET 4.0から追加されたライブラリです。 /// </remarks> [Sample] class TaskSamples07 : IExecutable { public void Execute() { // // タスクの戻り値は // Resultプロパティ // から取得できる。 // // 非同期処理内で例外が発生していた場合 // Resultプロパティにアクセスした段階で // 例外 (AggregateException) が発生するので注意。 // // タスクにて、内部で例外が発生していた場合に // 以下のメソッドにアクセスすると保留されていた // 例外が発生する. // // ・Resultプロパティ // ・Waitメソッド // // // 以下、いろいろな方法でタスクを作成して結果を取得. // var task1 = Task.Run(() => GetStringResult()); Output.WriteLine(task1.Result); var task2 = Task.Factory.StartNew(() => GetIntResult()); Output.WriteLine(task2.Result); var task3 = new Task<string>(() => GetStringResult()); task3.Start(); Output.WriteLine(task3.Result); var tokenSource = new CancellationTokenSource(); var task4 = Task.Run(() => GetDelayResult(tokenSource.Token), tokenSource.Token); try { // // 指定時間後にキャンセル. // CancellationTokenSource.Cancelで発生する例外は // OperationCanceledExceptionだが // タスクに対して、予め同じキャンセルトークンを渡している場合 // キャンセル例外が発生したことをタスクが認識して // TaskCanceledExceptionを発生させる. // tokenSource.CancelAfter(TimeSpan.FromMilliseconds(500)); Output.WriteLine(task4.Result); } catch (AggregateException aggreEx) { aggreEx.Handle(ex => { if (ex is TaskCanceledException) { Output.WriteLine("[CANCEL] {0}", ex); return true; } return false; }); } } internal int GetIntResult() { return 100; } internal string GetStringResult() { return "Hello world"; } internal async Task<string> GetDelayResult(CancellationToken token) { await Task.Delay(TimeSpan.FromMilliseconds(5000)); token.ThrowIfCancellationRequested(); return GetStringResult(); } } }
実行すると以下のようになります。
Hello world 100 Hello world [CANCEL] System.Threading.Tasks.TaskCanceledException: タスクが取り消されました。
過去の記事については、以下のページからご参照下さい。
- いろいろ備忘録日記まとめ
サンプルコードは、以下の場所で公開しています。
- いろいろ備忘録日記サンプルソース置き場