C#多线程Task创建
多线程常用函数:
一、Thread -- .Net 1.0
二、ThreadPool -- .Net 2.0
三、Task -- .Net 3.0 -- 推荐
3.1、Task创建
3.2、Task.Run 创建
3.3、Parallel使用
3.4、Task 其他函数
四、TaskFactory -- .Net 4.0
4.1、TaskFactory创建
4.2、Task.Factory.StartNew 创建
4.3、TaskFactory其他函数
五、lock 、Async、Await
5.1、lock
5.2、Async、Await
涉及知识点: Thread、ThreadPool 、Task、TaskFactory
多线程常用函数:
Thread.CurrentThread.ManagedThreadId --- 当前线程id
Thread.CurrentThread.IsThreadPoolThread --- 当前线程是否使用线程池
一、Thread -- .Net 1.0
优点:API特别丰富
缺陷:
1、线程资源是直接从操作系统中获取,在线程挂起时,存在延时情况,造成任务执行顺序混乱
2、线程个数没有限制,对于新手容易造成死机状态
常用函数:
Thread thread = new Thread(threadStart);
thread.Start(); //线程开启
thread.Suspend(); //线程挂起
thread.Resume(); //挂起线程恢复
thread.Join(); //线程阻塞,直到线程完成后,执行下一步
thread.IsBackground = true; //设置为后台线程
thread.Abort();//线程摧毁
二、ThreadPool -- .Net 2.0
优点:线程池会根据限定的数量去申请和释放
若空闲线程太少时,会自动向操作系统申请线程
若空闲线程太多时,会自动释放线程
缺陷:
API 特别少 -- 造成很难控制线程执行顺序
例程:
1 WaitCallback waitCallback = (x) => 2 { 3 Thread.Sleep(3000); 4 Console.WriteLine("Thread End"); 5 }; 6 ThreadPool.QueueUserWorkItem(waitCallback); 7 Console.WriteLine("完成");
三、Task -- .Net 3.0 -- 推荐
优点:1、线程池会根据限定的数量去申请和释放
若空闲线程太少时,会自动向操作系统申请线程
若空闲线程太多时,会自动释放线程 <summary>
2、 API丰富,便于控制
前期准备:
4个函数:1个无参、1个参数、2个参数、2参数+返回值
1 public static void DoSomeThing() 2 { 3 Console.WriteLine("Start"); 4 for (int i = 0; i < 10; i++) 5 { 6 Console.WriteLine($"--Method--{i}"); 7 } 8 Console.WriteLine("End"); 9 } 10 11 public static void DoSomeThing_1(string name) 12 { 13 Console.WriteLine("Start"); 14 for (int i = 0; i < 10; i++) 15 { 16 Console.WriteLine($"--Method--{i}"); 17 } 18 Console.WriteLine("End " + name); 19 } 20 public static void DoSomeThing_2(string name1, string name2) 21 { 22 Console.WriteLine("Start"); 23 for (int i = 0; i < 10; i++) 24 { 25 Console.WriteLine($"--Method--{i}"); 26 } 27 Console.WriteLine("End " + name1 + name2); 28 } 29 public static string DoSomeThing_2_1(string name1, string name2) 30 { 31 Console.WriteLine("Start"); 32 for (int i = 0; i < 10; i++) 33 { 34 Console.WriteLine($"--Method--{i}"); 35 } 36 Console.WriteLine("End " + name1 + name2); 37 return name1; 38 }
3.1、Task创建
1、无参
Task task = new Task(DoSomeThing);
task.Start();
2、一个参数
Task task = new Task((x)=>DoSomeThing_1((string)x),"XXXXXX");
task.Start();
3、一个参数
Task task = new Task(() => DoSomeThing_1("XXXXX"));
task.Start();
4、两个参数
Task task = new Task(() => DoSomeThing_2("XXXXX_1", "XXXXX_2"));
task.Start();
5、两个参数+返回值
Task<string> task = new Task<string>(() => DoSomeThing_2_1("XXXXX_1", "XXXXX_2"));
task.Start();
Console.WriteLine(task.Result);
3.2、Task.Run 创建
1、无参
Task.Run(DoSomeThing);
2、一个参数
Task.Run(()=>DoSomeThing_1("XXXXX"));
3、两个参数+返回值
Task<string> result = Task.Run(() => DoSomeThing_2_1("mask1", "mask2"));
Console.WriteLine(result.Result);
3.3、Parallel使用
Parallel 可以启动多线程,主线程也参与计算,节约一个线程
可以通过ParallelOptions轻松控制最大并发数量
缺点:主线程卡住
例程:
1 Parallel.Invoke( 2 () => 3 { 4 Console.WriteLine("Thread Start1"); 5 Thread.Sleep(3000); 6 Console.WriteLine("Thread End1"); 7 }, 8 () => 9 { 10 Console.WriteLine("Thread Start2"); 11 Thread.Sleep(3000); 12 Console.WriteLine("Thread End2"); 13 } 14 ); 15 Console.WriteLine("完成");
3.4、Task 其他函数
Task.WaitAny(tasks.ToArray()); //任意一个完成,继续
Task.WaitAll(tasks.ToArray()); // 全部完成,继续
例程:
1 List<Task> tasks = new List<Task>(); 2 tasks.Add(Task.Run(() => { Thread.Sleep(2000); Console.WriteLine("task1"); })); 3 tasks.Add(Task.Run(() => { Thread.Sleep(2000); Console.WriteLine("task2"); })); 4 tasks.Add(Task.Run(() => { Thread.Sleep(2000); Console.WriteLine("task3"); })); 5 tasks.Add(Task.Run(() => { Thread.Sleep(2000); Console.WriteLine("task4"); })); 6 7 Task.WaitAny(tasks.ToArray()); //任一一个完成,继续 -- 8 Console.WriteLine("XXX第一个完成"); 9 10 Task.WaitAll(tasks.ToArray()); // 全部完成,继续 11 Console.WriteLine("完成");
四、TaskFactory -- .Net 4.0
优点:1、线程池会根据限定的数量去申请和释放
若空闲线程太少时,会自动向操作系统申请线程
若空闲线程太多时,会自动释放线程 <summary>
2、 API丰富,便于控制
前期准备:
4个函数:1个无参、1个参数、2个参数、2参数+返回值
1 public static void DoSomeThing() 2 { 3 Console.WriteLine("Start"); 4 for (int i = 0; i < 10; i++) 5 { 6 Console.WriteLine($"--Method--{i}"); 7 } 8 Console.WriteLine("End"); 9 } 10 11 public static void DoSomeThing_1(string name) 12 { 13 Console.WriteLine("Start"); 14 for (int i = 0; i < 10; i++) 15 { 16 Console.WriteLine($"--Method--{i}"); 17 } 18 Console.WriteLine("End " + name); 19 } 20 public static void DoSomeThing_2(string name1, string name2) 21 { 22 Console.WriteLine("Start"); 23 for (int i = 0; i < 10; i++) 24 { 25 Console.WriteLine($"--Method--{i}"); 26 } 27 Console.WriteLine("End " + name1 + name2); 28 } 29 public static string DoSomeThing_2_1(string name1, string name2) 30 { 31 Console.WriteLine("Start"); 32 for (int i = 0; i < 10; i++) 33 { 34 Console.WriteLine($"--Method--{i}"); 35 } 36 Console.WriteLine("End " + name1 + name2); 37 return name1; 38 }
4.1、TaskFactory创建
1、无参
TaskFactory taskFactory = new TaskFactory();
taskFactory.StartNew(DoSomeThing);
2、一个参数
TaskFactory taskFactory = new TaskFactory();
taskFactory.StartNew((x)=>DoSomeThing_1((string)x), "XXXXX");
3、两个参数
TaskFactory taskFactory = new TaskFactory();
taskFactory.StartNew(() => DoSomeThing_2("XXXXX_1", "XXXXX_2"));
4、两个参数+返回值
TaskFactory taskFactory = new TaskFactory();
Task<string> result = taskFactory.StartNew(() => DoSomeThing_2_1("XXXXX_1", "XXXXX_2"));
Console.WriteLine(result.Result);
4.2、Task.Factory.StartNew 创建
1、无参
Task.Factory.StartNew(DoSomeThing);
2、一个参数
Task.Factory.StartNew((x) => DoSomeThing_1((string)x), "XXXXX");
3、两个参数
Task.Factory.StartNew(() => DoSomeThing_2("XXXXX_1", "XXXXX_2"));
4、两个参数+返回值
Task<string> result = Task.Factory.StartNew(() => DoSomeThing_2_1("XXXX_1", "XXXX_2"));
Console.WriteLine(result.Result);
4.3、TaskFactory其他函数
taskFactory.ContinueWhenAny //任意一个完成,继续
taskFactory.ContinueWhenAll // 全部完成,继续
List<Task> tasks = new List<Task>();
tasks.Add(Task.Run(() => { Thread.Sleep(2000); Console.WriteLine("task1"); }));
tasks.Add(Task.Run(() => { Thread.Sleep(2000); Console.WriteLine("task2"); }));
tasks.Add(Task.Run(() => { Thread.Sleep(2000); Console.WriteLine("task3"); }));
tasks.Add(Task.Run(() => { Thread.Sleep(2000); Console.WriteLine("task4"); }));
TaskFactory taskFactory = new TaskFactory();
taskFactory.ContinueWhenAny(tasks.ToArray(),
(x) =>
{ Console.WriteLine("初步完成"); });
taskFactory.ContinueWhenAll(tasks.ToArray(),
(x) =>
{ Console.WriteLine("全部完成"); });
五、lock 、Async、Await
5.1、lock
锁定的内容,多个线程同时访问时,需要排队进行
lock的标志,最好不用混用,一个标志配一把锁
class Program
{
public static void Main()
{
List<Task> tasks = new List<Task>();
tasks.Add(Task.Run(DoSomeThing));
tasks.Add(Task.Run(DoSomeThing));
Task.Run(tasks.ToArray);
Console.WriteLine("----");
}
//锁标志位创建
private static readonly Object LOCK = new Object();
public static void DoSomeThing()
{
//锁内容设置
lock (LOCK)
{
Console.WriteLine("Start");
for (int i = 0; i < 10; i++)
{
Console.WriteLine($"--Method--{i}");
}
Console.WriteLine("End");
}
}
}
5.2、Async、Await
Async 只能修饰 void、Task、Task<T> 方法 此类方法一般用Async结尾
Await 只能修饰 Task,用于等待任务完成
private void button2_Click(object sender, EventArgs e)
{
Task.Run(DoSomeThing);
Task.Run(DoSomeThing_1);
Console.WriteLine("------");
}
public async void DoSomeThing()
{
Console.WriteLine("---Start---");
await Task.Delay(1000);
for(int i = 0;i< 10;i++)
{
Console.WriteLine($"--{i}--");
}
Console.WriteLine("---End---");
}
public async void DoSomeThing_1()
{
Console.WriteLine("---Start---");
await Task.Delay(1000);
for (int i = 0; i < 10; i++)
{
Console.WriteLine($"--Method_2--{i}--");
}
Console.WriteLine("---End---");
}
————————————————
原文链接:https://blog.csdn.net/againknow/article/details/128750640