- Represents the producer side of a Task<TResult> unbound to a delegate, providing access to the consumer side through the Task property.
参考资料:
以下为本人调试时的代码:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace TaskCompletionSource_TResult
{
class Program
{
//Demonstrated features:
// TaskCompletionSource ctor()
// TaskCompletionSource.SetResult()
// TaskCompletionSource.SetException()
// Task.Result
//Expected results:
// The attempt to get t1.Result blocks for 1000ms until tcs1 gets signaled. 15 is print out.
// The attempt to get t2.Result blocks for 1000ms until tcs2 gets signaled. An exception is print out.
static void Main(string[] args)
{
TaskCompletionSource<int> tcs1 = new TaskCompletionSource<int>();
Task<int> t1 = tcs1.Task;
//Start a background task that will complete tcs1.Task
Task.Factory.StartNew(() =>
{
Thread.Sleep(1000);
tcs1.SetResult(15);
});
//The attempt to get the result of t1 blocks the current thread until the completion source gets signaled.
//It should be a wait of 1000 ms.
Stopwatch sw = Stopwatch.StartNew();
int result = t1.Result;
sw.Stop();
Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + " (ElapsedTime = " + sw.ElapsedMilliseconds + "), t1.result = " + result + " (expected 15)");
//------------------------------------------------------------------------------------------------------------
//Alternatively, an exception can be manually set on a TaskCompletionSource.Task
TaskCompletionSource<int> tcs2 = new TaskCompletionSource<int>();
Task<int> t2 = tcs2.Task;
//Start a background Task that will complete tcs2.Task with an exception
Task.Factory.StartNew(() =>
{
Thread.Sleep(1000);
tcs2.SetException(new InvalidOperationException("SIMULATED EXCEPTION"));
tcs2.SetResult(911);
});
//The attempt to get the result of t2 blocks the current thread until the completion source gets signaled with either
//a result or an exception.
//In either case it should be a wait of 1000ms.
sw = Stopwatch.StartNew();
try
{
result = t2.Result;
Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + " t2.Result succeeded. THIS WAS NOT EXCEPTION.");
}
catch (AggregateException e)
{
Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + " (ElapsedTime = " + sw.ElapsedMilliseconds + ")");
Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + " The following exceptions have been thrown by t2.Result : (THIS WAS EXPECTED)");
for (int j = 0; j < e.InnerExceptions.Count; j++)
{
Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + "\n------------------------------------------------------------------\n" + e.InnerExceptions[j].ToString());
}
}
Console.ReadLine();
}
}
}
运行结果: