1. 创建Task:
Console.WriteLine("Before task1, with thread id: {0}", Environment.CurrentManagedThreadId);
Console.WriteLine("=== Time before tasks begin ===");
Console.WriteLine(DateTime.Now.ToLongTimeString());
Task task1 = Task.Factory.StartNew(() =>
{
Console.WriteLine("In task1, with thread id: {0}", Environment.CurrentManagedThreadId);
Thread.Sleep(10000);
});
Console.WriteLine("Before task2 (after task1), with thread id: {0}", Environment.CurrentManagedThreadId);
Task task2 = Task.Factory.StartNew(() =>
{
Console.WriteLine("In task2, with thread id: {0}", Environment.CurrentManagedThreadId);
Thread.Sleep(10000);
});
Console.WriteLine("After task2, with thread id: {0}", Environment.CurrentManagedThreadId);
// Since a console application otherwise terminates, wait for both tasks to complete.
Task.WaitAll(new Task[] { task1, task2 });
Console.WriteLine("=== Time after tasks finish ===");
Console.WriteLine(DateTime.Now.ToLongTimeString());
运行得到如下结果:
Before task1, with thread id: 1
=== Time before tasks begin ===
7:05:13 PM
Before task2 (after task1), with thread id: 1
After task2, with thread id: 1
In task1, with thread id: 3
In task2, with thread id: 4
=== Time after tasks finish ===
7:05:23 PM
关于结果的几点说明:(1)两个task运行的不在主线程中;(2)每个task需要10秒,两个task也只需要10秒。在多核(多CPU)机器上,能提高性能。
2. 一个task可以创建一个或者多个子task。我们还可以设定task之间的依赖关系。比如:
private static void Process(string name, int secondsToSleep)
{
Console.WriteLine("In processing {0}, start at time: {1}", name,
DateTime.Now.ToLongTimeString());
Thread.Sleep(secondsToSleep * 1000);
Console.WriteLine("In processing {0}, end at time: {1}", name,
DateTime.Now.ToLongTimeString());
}
static void Main(string[] args)
{
var solution = new Task(() =>
{
var taskFactory = new TaskFactory(TaskCreationOptions.AttachedToParent,
TaskContinuationOptions.AttachedToParent);
var C = taskFactory.StartNew(() => Process("C", 10));
var E = taskFactory.StartNew(() => Process("E", 10));
var F = taskFactory.StartNew(() => Process("F", 10));
var B = C.ContinueWith(t => Process("B", 10));
var D = taskFactory.ContinueWhenAll(new Task[] { E, F },
tasks => Process("D", 10));
var A = taskFactory.ContinueWhenAll(new Task[] { B, D },
tasks => Process("A", 10));
});
solution.Start();
solution.Wait();
}
输出为:
In processing C, start at time: 8:02:09 PM
In processing E, start at time: 8:02:09 PM
In processing F, start at time: 8:02:09 PM
In processing F, end at time: 8:02:19 PM
In processing C, end at time: 8:02:19 PM
In processing E, end at time: 8:02:19 PM
In processing B, start at time: 8:02:19 PM
In processing D, start at time: 8:02:19 PM
In processing B, end at time: 8:02:29 PM
In processing D, end at time: 8:02:29 PM
In processing A, start at time: 8:02:29 PM
In processing A, end at time: 8:02:39 PM
实验机器的CPU为四核。不同机器的输出可能略有不同。
3. await
private static async Task<int> LongTaskAsyn()
{
Console.WriteLine("In DoTask, before GetStringAsync.");
Console.WriteLine("Thread id: {0}.\n", Environment.CurrentManagedThreadId);
Task<String> task = new HttpClient().GetStringAsync("http://www.microsoft.com");
String text = await task;
Console.WriteLine("In DoTask, after GetStringAsync.");
Console.WriteLine("Thread id: {0}.\n", Environment.CurrentManagedThreadId);
return text.Length;
}
static void Main(string[] args)
{
Console.WriteLine("In Main, before LongTaskAsyn.");
Console.WriteLine("Thread id: {0}.\n", Environment.CurrentManagedThreadId);
Task<int> task = LongTaskAsyn();
Console.WriteLine("In Main, after LongTaskAsyn.");
Console.WriteLine("Thread id: {0}.\n", Environment.CurrentManagedThreadId);
var result = task.GetAwaiter().GetResult();
}
运行结果:
In Main, before LongTaskAsyn.
Thread id: 1.
In DoTask, before GetStringAsync.
Thread id: 1.
In Main, after LongTaskAsyn.
Thread id: 1.
In DoTask, after GetStringAsync.
Thread id: 9.
结果说明:(1)调用async函数,在函数执行结束前就返回,接着执行之后的语句;(2)await等到async函数的结果之后,从await之后的语句开始在另外一个线程执行。