多线程(1-4-Task)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
/*
1:可以看到Task和Thread一样,位于System.Threading命名空间下;
2:两种方式创建两个task,并让他们运行。可以看到通过构造函数创建的task,必须手动Start,而通过工厂创建的Task直接就启动了。
*/
namespace TaskUse
{
class Program
{
static void Main(string[] args)
{
#region Task创建
/// Task 3.0
/// 使用的是线程池的线程 全部是后台线程
/// API很强大
///
/// 多线程:业务是可以并发执行
///
/// 千万不要在Task里面去启动Task
//Console.WriteLine("This is Main thread ;Thread.CurrentThread.ManagedThreadId={0}", Thread.CurrentThread.ManagedThreadId);
//var task1 = new Task(() => { Console.WriteLine("Hello, task; Thread.CurrentThread.ManagedThreadId={0}", Thread.CurrentThread.ManagedThreadId); });
//task1.Start();
//var task2 = Task.Factory.StartNew(() => { Console.WriteLine("Hello, task started by task factory ;Thread.CurrentThread.ManagedThreadId={0}", Thread.CurrentThread.ManagedThreadId); });
//Console.ReadLine();
#endregion
#region Task的生命周期
/*
从我们可以得出Task的简略生命周期:
Created:表示默认初始化任务,但是“工厂创建的”实例直接跳过。
WaitingToRun: 这种状态表示等待任务调度器分配线程给任务执行。
RanToCompletion:任务执行完毕
*/
var task1 = new Task(() =>
{
Console.WriteLine("Begin");
Thread.Sleep(2000);
Console.WriteLine("Finished");
});
Console.WriteLine("Before start:"+task1.Status);
task1.Start();
Console.WriteLine("After start:"+task1.Status);
task1.Wait(); //等待任务执行完成
Console.WriteLine("After Finish:"+task1.Status);
Console.Read();
运行结果图一:
#endregion
#region Task的任务控制
//Task.Wait()
//Task.WaitAll();
//Task.WaitAny();
//Task.ContinueWith()
/*
var task1 = new Task(() =>
{
Console.WriteLine("Task 1 Begin");
System.Threading.Thread.Sleep(2000);
Console.WriteLine("Task 1 Finish");
});
var task2 = new Task(() =>
{
Console.WriteLine("Task 2 Begin");
System.Threading.Thread.Sleep(3000);
Console.WriteLine("Task 2 Finish");
});
task1.Start();
task2.Start();
// Task.WaitAll(task1, task2);
// Console.WriteLine("All task finished!");
int i= Task.WaitAny(task1,task2); 返回值为已完成的任务在 tasks 数组参数中的索引,如果发生超时,则为 -1。
Console.WriteLine("return value={0}",i);
Console.Read();
运行结果图二:
*/
//Task.ContinueWith()----就是在第一个Task完成后自动启动下一个Task,实现Task的延续
//var task3 = new Task(() =>
//{
// Console.WriteLine("Task 3 Begin");
// System.Threading.Thread.Sleep(3000);
// Console.WriteLine("Task 3 Finish");
//});
//var task4 = new Task(() =>
//{
// Console.WriteLine("Task 4 Begin");
// System.Threading.Thread.Sleep(6000);
// Console.WriteLine("Task 4 Finish");
//});
//task3.Start();
//task4.Start();
//var result = task3.ContinueWith(task => {
// TaskStatus task4Status= task4.Status;
// Console.WriteLine("task3.finished");
// return "this is task result; task3Status=" + task.Status.ToString() + ",tak4Status=" + task4Status.ToString() + "!";
//});
//Console.WriteLine(result.Result.ToString()); //task3完成之后,开始执行后面的内容,并且取得task的返回值。
//Console.Read();
运行结果图三:
#endregion
#region 任务完成开启新任务
//任务并没有提供回调事件来通知完成,它通过启用一个新任务的方式来完成类似的功能;
//ContinueWith方法可以在一个任务完成的时候发起一个新的任务,这种方式天然就支持了任务的完成通知:可以在新任务中获取原任务的结果值
//
//Task.Factory.StartNew(() => { return "canshu"; }).ContinueWith(ss => { Console.WriteLine(ss.Result); });
//Console.Read();
//var task=Task.Factory.StartNew(()=>{return 1;});
//Console.WriteLine(task.Result);
//var result = task.ContinueWith(aa => { return aa.Result + 1; });
//Console.WriteLine(result.Result);
//Console.Read();
#endregion
#region TaskFactory的用法
//Console.WriteLine("This is main Thread start----Thread.CurrentThread.ManagedThreadId={0}", Thread.CurrentThread.ManagedThreadId.ToString("00"));
//string result = null;
// TaskFactory taskFactory1 = Task.Factory; //(1)利用Tsak的静态成员
TaskFactory taskFactory2 = new TaskFactory(); //(2)第二种方式创建TaskFactory
//List taskList = new List();
//taskList.Add(taskFactory2.StartNew(() => DoSomething("btnTask_Click_002")));
//taskList.Add(taskFactory2.StartNew(() => DoSomething("btnTask_Click_001")));
//taskList.Add(taskFactory2.StartNew(() => DoSomething("btnTask_Click_003")));
//taskList.Add(taskFactory2.StartNew(() => DoSomething("btnTask_Click_004")));
//taskList.Add(taskFactory2.StartNew(() => DoSomething("btnTask_Click_005")));
//需要多线程加快速度 同时又要求全部完成后,才能返回
//多业务操作 希望并发,但是全部完成后,才能返回
//Task.WaitAll(taskList.ToArray()); //卡界面 (因为是主线程在等待子线程全部完成)
//需要多线程加快速度 同时又要求某个完成后,才能返回
//多业务操作 希望并发,但是某个完成后,才能返回
// Task.WaitAny(taskList.ToArray()); //卡界面
//Task task = taskFactory2.StartNew(t => DoSomething("btnTask_Click_006"), "煎饼果子").ContinueWith(t => Console.WriteLine("t.AsyncState={0}", t.AsyncState)); //这里调用的DoSomething是没有返回值的
//Console.WriteLine("-----task.AsyncState={0}-----", task.AsyncState);
//Task task2 = taskFactory2.StartNew(() => DoSomethingHasReturnValue("btnTask_Click_007")).ContinueWith(t =>
//{
// result = t.Result;
// Console.WriteLine("t.Result={0}", t.Result);
//}); //这里是有返回值
//task2.Wait();
//Console.WriteLine("**result={0}**",result);
//Task intTask = taskFactory2.StartNew(()=>123);
//int iResult = intTask.Result;
//Console.WriteLine("This is main Thread end----Thread.CurrentThread.ManagedThreadId={0}", Thread.CurrentThread.ManagedThreadId.ToString("00"));
//Console.Read();
#endregion
#region 将方法作为参数
//Console.WriteLine("This is main Thread start----Thread.CurrentThread.ManagedThreadId={0}", Thread.CurrentThread.ManagedThreadId.ToString("00"));
//Task.Factory.StartNew(new Action(() =>
//{
// BeginCalculate(() => {
// Console.WriteLine("This is action start----Thread.CurrentThread.ManagedThreadId={0}", Thread.CurrentThread.ManagedThreadId.ToString("00"));
// for (int i = 0; i < 100; i++)
// {
// Console.WriteLine("Action_" + i + "");
// }
// Console.WriteLine("This is action end----Thread.CurrentThread.ManagedThreadId={0}", Thread.CurrentThread.ManagedThreadId.ToString("00"));
// });
//}));
//Console.WriteLine("This is main Thread end----Thread.CurrentThread.ManagedThreadId={0}", Thread.CurrentThread.ManagedThreadId.ToString("00"));
//Console.Read();
#endregion
}
private static void DoSomething(string name)
{
Console.WriteLine("*************DoSomething Start {0} ----Thread.CurrentThread.ManagedThreadId={1}---{2}**",name,Thread.CurrentThread.ManagedThreadId.ToString("00"),DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
long IResult=0;
for(int i=0;i<1000;i++)
{
IResult+=i;
}
Console.WriteLine("*************DoSomething End {0} ----Thread.CurrentThread.ManagedThreadId={1}---{2}**", name, Thread.CurrentThread.ManagedThreadId.ToString("00"), DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
}
private static string DoSomethingHasReturnValue(string name)
{
Console.WriteLine("*************DoSomethingHasReturnValue Start {0} ----Thread.CurrentThread.ManagedThreadId={1}---{2}**", name, Thread.CurrentThread.ManagedThreadId.ToString("00"), DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
long IResult = 0;
for (int i = 0; i < 1000; i++)
{
IResult += i;
}
Console.WriteLine("*************DoSomethingHasReturnValue End {0} ----Thread.CurrentThread.ManagedThreadId={1}---{2}**", name, Thread.CurrentThread.ManagedThreadId.ToString("00"), DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
return IResult.ToString();
}
private static void BeginCalculate(Action action)
{
Console.WriteLine("This is beginCalculate start----Thread.CurrentThread.ManagedThreadId={0}", Thread.CurrentThread.ManagedThreadId.ToString("00"));
for (int i = 0; i < 20; i++)
{
Console.WriteLine("BeginCalculate_" + i + "");
}
Console.WriteLine("This is beginCalculate end----Thread.CurrentThread.ManagedThreadId={0}", Thread.CurrentThread.ManagedThreadId.ToString("00"));
action();//执行委托
}
}
}