.NET中的Task

来源:互联网 发布:php 文章内链 编辑:程序博客网 时间:2024/06/08 05:03

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 PMBefore task2 (after task1), with thread id: 1After task2, with thread id: 1In task1, with thread id: 3In 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 PMIn processing E, start at time: 8:02:09 PMIn processing F, start at time: 8:02:09 PMIn processing F, end at time: 8:02:19 PMIn processing C, end at time: 8:02:19 PMIn processing E, end at time: 8:02:19 PMIn processing B, start at time: 8:02:19 PMIn processing D, start at time: 8:02:19 PMIn processing B, end at time: 8:02:29 PMIn processing D, end at time: 8:02:29 PMIn processing A, start at time: 8:02:29 PMIn 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之后的语句开始在另外一个线程执行。


0 0