C# Task 总结
Σίσυφος1900 2024-08-27 10:05:02 阅读 75
一、概述
https://blog.csdn.net/m0_48667560/article/details/133364455
Task基础介绍 Task的创建 有四种方式Task的传入参数Task获得返回值
*Action 和Func 的区别
Action:
没有参数同时没有返回值
Func委托:
Func有返回值 有参数,但是参数最多是16个
<code>-------------------Func 没有返回值类型的委托------------------------------
Func至少0个输入参数,至多16个输入参数,根据返回值泛型返回。必须有返回值,不可void。
Func<int> 表示没有输入参参,返回值为int类型的委托。
Func<object, string, int> 表示传入参数为object, string ,返回值为int类型的委托。
Func<object, string, int> 表示传入参数为object, string, 返回值为int类型的委托。
Func < T1,T2,,T3,int> 表示传入参数为T1,T2,,T3(泛型),返回值为int类型的委托。
Task 的优点
在任务启动后,可以随时以任务延续的形式注册回调。通过使用 ContinueWhenAll 和 ContinueWhenAny 方法或者 WaitAll 方法或 WaitAny 方法,协调多个为了响应 Begin_ 方法而执行的操作。在同一 Task 对象中封装异步 I/O 绑定和计算绑定操作。监视 Task 对象的状态。使用 TaskCompletionSource 将操作的状态封送到 Task 对象。
二、Task 的创建
public Task(Action action);
public Task(Action<object> action, object state);
public Task(Action action, CancellationToken cancellationToken);
public Task(Action action, TaskCreationOptions creationOptions);
public Task(Action<object> action, object state, CancellationToken cancellationToken);
public Task(Action<object> action, object state, TaskCreationOptions creationOptions);
public Task(Action action, CancellationToken cancellationToken, TaskCreationOptions creationOptions);
public Task(Action<object> action, object state, CancellationToken cancellationToken, TaskCreationOptions creationOptions);
task的建立有四种方式
1、使用委托和方法
// 第一种方法 使用委托和方法
Task task = new Task(new Action(PringtMsg));
2、 使用匿名委托
// 使用匿名委托
Task taskdelegate = new Task(delegate {
Console.WriteLine("hello world taskdelegate");
});
3、使用lamdba 匿名委托
// 第三种方式 使用lamdba和匿名方式
Task task_lamdba= new Task(() =>
{
Console.WriteLine("hello world task_lamdba");
});
4、使用lamdba+方法委托
//第二种 使用lamdba 表达式的方法
Task lamdba = new Task(() => PringtMsg2());
测试代码:
static void Main()
{
//----------------------------------------------------------创建------------------------------------------------------------------
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
// 第一种方法 使用委托和方法
Task task = new Task(new Action(PringtMsg));
// 使用匿名委托
Task taskdelegate = new Task(delegate {
Console.WriteLine("hello world taskdelegate");
});
//第二种 使用lamdba 表达式的方法
Task lamdba = new Task(() => PringtMsg2());
// 第三种方式 使用lamdba和匿名方式
Task task_lamdba= new Task(() =>
{
Console.WriteLine("hello world task_lamdba");
});
task.Start();
taskdelegate.Start();
lamdba.Start();
task_lamdba.Start();
Application.Run(new Form1());
Console.Read();
}
private static void PringtMsg()
{
Console.WriteLine("hello world");
}
private static void PringtMsg2()
{
Console.WriteLine("hello world2222 ");
}
}
三、Task 中传入参数
在创建task 的时候我们在构造函数中传入一个System.Action,想向Task传入参素,只能用System.Action<object>
string[] messages = { "First task", "Second task", "Third task", "Fourth task" };
foreach (var item in messages)
{
Task taskm = new Task((s)=>Print((string)s),item);
// 第二种方式
Task t1 = new Task(()=> Print222(item));
taskm.Start();
t1.Start();
}
private static void Print(string msg)
{
Console.WriteLine($"print message : {msg}");
}
private static void Print222(string msg)
{
Console.WriteLine($"print Print222 : {msg}");
}
四、Task 有返回值
task.result 在获取结果的时候会阻塞线程,等到获取结果之后才会执行后面的程序代码
<code>//=============================================Task 返回值=====================================================================
Task<int> sum = new Task<int>(()=>GetSum());
sum.Start();
Console.WriteLine($"task result is {sum.Result}");
//============================================= Task 返回值 =====================================================================
private static int GetSum()
{
int sum = 0;
for (int i = 0; i < 10; i++)
{
sum = sum + i;
Thread.Sleep(100);
}
return sum;
}
传入参数 输出结果
=============================================传入参数 Task 返回值=====================================================================
Task<double> ta = new Task<double>((i)=>GetNum((int)i),100);
ta.Start();
Console.WriteLine($"ta result is {ta.Result}");
=============================================传入参数 Task 返回值=====================================================================
Console.Read();
private static double GetNum(int len)
{
double sum = 0;
for (int i = 0; i <= len; i++)
{
sum = sum + i;
Thread.Sleep(10);
}
return sum;
}
//-----------------------------------------------------Action 没有返回值类型的委托------------------------------------------------------------------
Func func = fun1;
Task.Factory.StartNew(new Action(func)); // 没有参数
//-----------------------------------------------------Func 没有返回值类型的委托------------------------------------------------------------------
//Func至少0个输入参数,至多16个输入参数,根据返回值泛型返回。必须有返回值,不可void。
//Func<int> 表示没有输入参参,返回值为int类型的委托。
//Func<object, string, int> 表示传入参数为object, string ,返回值为int类型的委托。
//Func<object, string, int> 表示传入参数为object, string, 返回值为int类型的委托。
//Func < T1,T2,,T3,int> 表示传入参数为T1,T2,,T3(泛型),返回值为int类型的委托。
// 没有参数
Func func78787 = delegate ()
{
Console.WriteLine("func78787---------");
};
Task.Run(()=> { func78787(); });
// 只有一个参数
// action<object>
{
Task.Factory.StartNew(fun2, " 只有一个参数 9999999999999999999999");
Task.Run(() => { fun2(" 只有一个参数 88888888888888888888888888 "); });
}
// func 方法 一个参数 有返回值类型的委托
var s = Task<int>.Factory.StartNew(new Func<object, int>(F4),20);
Console.WriteLine(s.Result);
//func委托 返回值
// 在Task 中只显示返回值
//有两个参数 并且有返回值
var niuni=Task<bool>.Factory.StartNew(new Func<bool>(() => FunWithMultiPara(20, "2")));
Console.WriteLine(niuni.Result);
Task.Factory.StartNew<TResualt>
<code> // ========================================================================================================================
Task<int> factory_tesk = Task.Factory.StartNew<int>((n) =>
{
// 这里的M变量名是不能和上面的重复的
int M = 0;
for (int i = 0; i <= (int)n; i++)
{
M = M + i;
}
return M;
}, 100);
Console.WriteLine($"sum = {factory_tesk.Result}");
五、Wait
Wait()
Wait() 等待执行调用任务完成,然后执行下一步; 即阻塞了主线程
<code> static void Main()
{
Console.WriteLine($"主线程{Thread.CurrentThread.ManagedThreadId}开启");
var t1 = Task.Run(() =>
{
Console.WriteLine($"T1 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
Thread.Sleep(10000);
});
t1.Wait();
var t2 = Task.Run(() =>
{
Console.WriteLine($"T2 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
Thread.Sleep(5000);
});
t2.Wait();
var t3 = Task.Run(() =>
{
Console.WriteLine($"T3 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
Thread.Sleep(500);
});
t3.Wait();
//t3.ContinueWith(t=> {
// Console.WriteLine($"T3 ContinueWith{Thread.CurrentThread.ManagedThreadId}处理业务");
// Thread.Sleep(5000);
//});
var t4 = Task.Run(() =>
{
Console.WriteLine($"T4 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
Thread.Sleep(2);
});
t4.Wait();
Console.WriteLine($"主线程{Thread.CurrentThread.ManagedThreadId}完成");
Console.ReadLine();
}
ContinueWith()
<code> static void Main()
{
Console.WriteLine($"主线程{Thread.CurrentThread.ManagedThreadId}开启");
var t1 = Task.Run(() =>
{
Console.WriteLine($"T1 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
Thread.Sleep(10000);
});
var t2 = Task.Run(() =>
{
Console.WriteLine($"T2 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
Thread.Sleep(5000);
});
var t3 = Task.Run(() =>
{
Console.WriteLine($"T3 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
Thread.Sleep(500);
});
t3.ContinueWith(t=> {
Console.WriteLine($"T3 ContinueWith{Thread.CurrentThread.ManagedThreadId}处理业务");
Thread.Sleep(5000);
});
var t4 = Task.Run(() =>
{
Console.WriteLine($"T4 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
Thread.Sleep(2);
});
Console.WriteLine($"主线程{Thread.CurrentThread.ManagedThreadId}完成");
Console.ReadLine();
}
Task.WaitAll
task.WaitAll等到所有任务都完成之后,才进行主线程的下一步操作,即阻塞主线程
<code> static void Main()
{
Console.WriteLine($"主线程{Thread.CurrentThread.ManagedThreadId}开启");
var t1 = Task.Run(() =>
{
Console.WriteLine($"T1 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
Thread.Sleep(10000);
});
//t1.Wait();
var t2 = Task.Run(() =>
{
Console.WriteLine($"T2 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
Thread.Sleep(5000);
});
// t2.Wait();
var t3 = Task.Run(() =>
{
Console.WriteLine($"T3 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
Thread.Sleep(500);
});
// t3.Wait();
//t3.ContinueWith(t=> {
// Console.WriteLine($"T3 ContinueWith{Thread.CurrentThread.ManagedThreadId}处理业务");
// Thread.Sleep(5000);
//});
var t4 = Task.Run(() =>
{
Console.WriteLine($"T4 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
Thread.Sleep(2);
});
// t4.Wait();
List<Task> allTask = new List<Task> {t1,t2,t3,t4 };
Task.WaitAll(allTask.ToArray());
Console.WriteLine($"主线程{Thread.CurrentThread.ManagedThreadId}完成");
Console.ReadLine();
}
静态方法Task.WaitAny
任意一个完成就执行下面的代码
<code> static void Main()
{
Console.WriteLine($"主线程{Thread.CurrentThread.ManagedThreadId}开启");
var t1 = Task.Run(() =>
{
Console.WriteLine($"T1 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
Thread.Sleep(10000);
});
//t1.Wait();
var t2 = Task.Run(() =>
{
Console.WriteLine($"T2 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
Thread.Sleep(5000);
});
// t2.Wait();
var t3 = Task.Run(() =>
{
Console.WriteLine($"T3 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
Thread.Sleep(500);
});
// t3.Wait();
//t3.ContinueWith(t=> {
// Console.WriteLine($"T3 ContinueWith{Thread.CurrentThread.ManagedThreadId}处理业务");
// Thread.Sleep(5000);
//});
var t4 = Task.Run(() =>
{
Console.WriteLine($"T4 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
Thread.Sleep(2);
});
// t4.Wait();
List<Task> allTask = new List<Task> {t1,t2,t3,t4 };
//Task.WaitAll(allTask.ToArray());
Task.WaitAny(allTask.ToArray());
Console.WriteLine($"主线程{Thread.CurrentThread.ManagedThreadId}完成");
Console.ReadLine();
}
任务工厂Task.Factory.ContinueWhenAll
当ContinueWhenAll中所有任务都完成时执行回调方法,不阻塞主线程
<code> static void Main()
{
Console.WriteLine($"主线程{Thread.CurrentThread.ManagedThreadId}开启");
var t1 = Task.Run(() =>
{
Console.WriteLine($"T1 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
Thread.Sleep(10000);
});
//t1.Wait();
var t2 = Task.Run(() =>
{
Console.WriteLine($"T2 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
Thread.Sleep(5000);
});
// t2.Wait();
var t3 = Task.Run(() =>
{
Console.WriteLine($"T3 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
Thread.Sleep(500);
});
// t3.Wait();
//t3.ContinueWith(t=> {
// Console.WriteLine($"T3 ContinueWith{Thread.CurrentThread.ManagedThreadId}处理业务");
// Thread.Sleep(5000);
//});
var t4 = Task.Run(() =>
{
Console.WriteLine($"T4 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
Thread.Sleep(2);
});
// t4.Wait();
List<Task> allTask = new List<Task> {t1,t2,t3,t4 };
//Task.WaitAll(allTask.ToArray());
//Task.WaitAny(allTask.ToArray());
Task.Factory.ContinueWhenAll(allTask.ToArray(),task=>
{
Console.WriteLine("所有子线程都已经完成了");
});
Console.WriteLine($"主线程{Thread.CurrentThread.ManagedThreadId}完成");
Console.ReadLine();
}
Thread.Sleep与Task.Delay的区别
Thread.Sleep在延期时间内会阻塞主线程,例如: Thread.Sleep(5000),在UI界面中会卡顿界面5秒,界面无法执行其他操作,原因是Thread属性IsBackground默认为前台线程,
Task.Delay(5000)延时期间不会阻塞主线程
六、线程同步
线程不安全:多线程同时修改一个变量;或者一个线程修改,一个线程读取,则可能出现BUG
线程同步的方法有:Mutex、Monitor、lock
lock
static string str= "abcd";
static int Tnum = 10;
static void BuyTickets()
{
while (true)
{
lock(str)
{
if (Tnum>0)
{
Thread.Sleep(1000);
Console.WriteLine(Thread.CurrentThread.Name+" ---- 票数 "+Tnum--);
}
}
}
}
static void Main()
{
Thread ta = new Thread(BuyTickets);
ta.Name = "线程 一";
Thread tb = new Thread(BuyTickets);
tb.Name = "线程 二";
Thread tc = new Thread(BuyTickets);
tc.Name = "线程 三";
Thread td = new Thread(BuyTickets);
td.Name = "线程 四";
ta.Start();
tb.Start();
tc.Start();
td.Start();
Console.ReadLine();
}
七、线程异步
理解异步函数async和await的用法_async await用法-CSDN博客
理解异步函数async和await的用法_async await用法-CSDN博客
async 是异步的意思
表示是一个异步的函数,而await 也只能在这个函数中使用,不能单独使用,其返回值是一个Promise对象,如果 Promise的状态变成了 resolve 或者 rejcet,那么 async函数会恢复执行。并会阻塞该函数内后面的代码
await 可以理解为async await
await 只能在async 的函数中使用
async 表示一个异步的方法,而await 是用来等待这个方法执行的
async和await
不加async 和await
static void timeout()
{
Task.Run(()=> {
for (int i = 0; i < 10; i++)
{
Console.WriteLine(" ----------- "+i.ToString());
}
});
Task.Run(() => {
for (int i = 0; i < 10; i++)
{
Console.WriteLine(" def " + i.ToString());
}
});
}
static void Main()
{
Console.WriteLine(" 开始 ");
timeout();
Console.WriteLine(" 结束 ");
Console.ReadLine();
}
从结果看是无序的
加async和await
<code> static async void timeout()
{
await Task.Run(()=> {
for (int i = 0; i < 10; i++)
{
Console.WriteLine(" ----------- "+i.ToString());
}
});
await Task.Run(() => {
for (int i = 0; i < 10; i++)
{
Console.WriteLine(" def " + i.ToString());
}
});
}
static void Main()
{
Console.WriteLine(" 开始 ");
timeout();
Console.WriteLine(" 结束 ");
Console.ReadLine();
}
结果如下:
<code> static async void AsyncMethond()
{
Console.WriteLine("开始异步代码");
// 异步方法,当使用await 的时候是使用task 的异步任务,否则还是同步执行
var result = await MyMethod();
Console.WriteLine("异步代码执行完毕" + result.ToString());
}
static async Task<int> MyMethod()
{
for (int i = 0; i < 5; i++)
{
Console.WriteLine("异步执行" + i.ToString() + "..");
await Task.Delay(10); //模拟耗时操作
}
return 100;
}
/// <summary>
/// main 方法不能使用 async
/// </summary>
static void Main()
{
Console.WriteLine("主线程测试开始..");
AsyncMethond();
Thread.Sleep(20000);
Console.WriteLine("主线程测试结束..");
Console.ReadLine();
}
案例二
在main 函数中是不能使用await 的
<code> static async void test()
{
log("test: await之前");
await doo(); // await 是等待doo 里面的都执行完之后才能打印下面的log
log("test: await之后");
}
static async Task doo()
{
// await Task 每个上面都是按照顺序输出执行的
log("doo: Task结果:" + await Task.Run(() => { Thread.Sleep(1000); log("Task"); return 1; }));
log("doo: Task结果:" + await Task.Run(() => { Thread.Sleep(1000); log("Task"); return 2; }));
log("doo: Task结果:" + await Task.Run(() => { Thread.Sleep(1000); log("Task"); return 3; }));
Thread.Sleep(1000);
Console.WriteLine("doo中在Task外的Thread.Sleep执行完毕");
}
static void log(string msg)
{
Console.WriteLine("{0}: {1}", Thread.CurrentThread.ManagedThreadId, msg);
}
static void Main()
{
Console.WriteLine(" 开始 ");
test(); // test 前面没有await 所以会执行下面 log("Main:调用test后"); 的日值
log("Main:调用test后");
Thread.Sleep(Timeout.Infinite);
Console.ReadLine();
}
修改:给task 上有int 的返回值
<code> static async void test()
{
log("test: await之前");
// await doo(); // await 是等待doo 里面的都执行完之后才能打印下面的log
Console.WriteLine("doo结果:{0}", await doo());
log("test: await之后");
}
//static async Task doo()
//{
// // await Task 每个上面都是按照顺序输出执行的
// log("doo: Task结果:" + await Task.Run(() => { Thread.Sleep(1000); log("Task"); return 1; }));
// log("doo: Task结果:" + await Task.Run(() => { Thread.Sleep(1000); log("Task"); return 2; }));
// log("doo: Task结果:" + await Task.Run(() => { Thread.Sleep(1000); log("Task"); return 3; }));
// Thread.Sleep(1000);
// Console.WriteLine("doo中在Task外的Thread.Sleep执行完毕");
//}
static async Task<int> doo()
{
// await Task 每个上面都是按照顺序输出执行的
var v1 = await Task.Run(() => { Thread.Sleep(1000); log("Task 1"); return 1; });
var v2 = await Task.Run(() => { Thread.Sleep(1000); log("Task 2"); return 2; });
var v3 = await Task.Run(() => { Thread.Sleep(1000); log("Task 3"); return 3; });
//不使用 await 线程池线程
ThreadPool.QueueUserWorkItem(_=> {
Thread.Sleep(1000);
Console.WriteLine("ThreadPool.QueueUserWorkItem");
});
_ = Task.Run(() =>
{
Thread.Sleep(1000);
Console.WriteLine("Task.Run");
});
return v1 + v2 + v3;
Console.WriteLine("doo中在Task外的Thread.Sleep执行完毕");
}
static void log(string msg)
{
Console.WriteLine("{0}: {1}", Thread.CurrentThread.ManagedThreadId, msg);
}
static void Main()
{
Console.WriteLine(" 开始 ");
test(); // test 前面没有await 所以会执行下面 log("Main:调用test后"); 的日值
log("Main:调用test后");
Thread.Sleep(Timeout.Infinite);
Console.ReadLine();
}
全部代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading.Tasks;
using System.Threading;
namespace TaskTest
{
static class Program
{
static async void test()
{
log("test: await之前");
// await doo(); // await 是等待doo 里面的都执行完之后才能打印下面的log
Console.WriteLine("doo结果:{0}", await doo());
log("test: await之后");
}
//static async Task doo()
//{
// // await Task 每个上面都是按照顺序输出执行的
// log("doo: Task结果:" + await Task.Run(() => { Thread.Sleep(1000); log("Task"); return 1; }));
// log("doo: Task结果:" + await Task.Run(() => { Thread.Sleep(1000); log("Task"); return 2; }));
// log("doo: Task结果:" + await Task.Run(() => { Thread.Sleep(1000); log("Task"); return 3; }));
// Thread.Sleep(1000);
// Console.WriteLine("doo中在Task外的Thread.Sleep执行完毕");
//}
static async Task<int> doo()
{
// await Task 每个上面都是按照顺序输出执行的
var v1 = await Task.Run(() => { Thread.Sleep(1000); log("Task 1"); return 1; });
var v2 = await Task.Run(() => { Thread.Sleep(1000); log("Task 2"); return 2; });
var v3 = await Task.Run(() => { Thread.Sleep(1000); log("Task 3"); return 3; });
//不使用 await 线程池线程
ThreadPool.QueueUserWorkItem(_=> {
Thread.Sleep(1000);
Console.WriteLine("ThreadPool.QueueUserWorkItem");
});
_ = Task.Run(() =>
{
Thread.Sleep(1000);
Console.WriteLine("Task.Run");
});
return v1 + v2 + v3;
Console.WriteLine("doo中在Task外的Thread.Sleep执行完毕");
}
static void log(string msg)
{
Console.WriteLine("{0}: {1}", Thread.CurrentThread.ManagedThreadId, msg);
}
static void Main()
{
Console.WriteLine(" 开始 ");
test(); // test 前面没有await 所以会执行下面 log("Main:调用test后"); 的日值
log("Main:调用test后");
Thread.Sleep(Timeout.Infinite);
Console.ReadLine();
}
static async void timeout()
{
await Task.Run(()=> {
for (int i = 0; i < 10; i++)
{
Console.WriteLine(" ----------- "+i.ToString());
}
});
await Task.Run(() => {
for (int i = 0; i < 10; i++)
{
Console.WriteLine(" def " + i.ToString());
}
});
}
static void Main77()
{
Console.WriteLine(" 开始 ");
timeout();
Console.WriteLine(" 结束 ");
Console.ReadLine();
}
/// <summary>
/// The main entry point for the application.
/// </summary>
///
static string str= "abcd";
static int Tnum = 10;
static void BuyTickets()
{
while (true)
{
lock(str)
{
if (Tnum>0)
{
Thread.Sleep(1000);
Console.WriteLine(Thread.CurrentThread.Name+" ---- 票数 "+Tnum--);
}
}
}
}
static void Main66()
{
Thread ta = new Thread(BuyTickets);
ta.Name = "线程 一";
Thread tb = new Thread(BuyTickets);
tb.Name = "线程 二";
Thread tc = new Thread(BuyTickets);
tc.Name = "线程 三";
Thread td = new Thread(BuyTickets);
td.Name = "线程 四";
ta.Start();
tb.Start();
tc.Start();
td.Start();
Console.ReadLine();
}
static void Main2()
{
Console.WriteLine($"主线程{Thread.CurrentThread.ManagedThreadId}开启");
var t1 = Task.Run(() =>
{
Console.WriteLine($"T1 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
Thread.Sleep(10000);
});
//t1.Wait();
var t2 = Task.Run(() =>
{
Console.WriteLine($"T2 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
Thread.Sleep(5000);
});
// t2.Wait();
var t3 = Task.Run(() =>
{
Console.WriteLine($"T3 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
Thread.Sleep(500);
});
// t3.Wait();
//t3.ContinueWith(t=> {
// Console.WriteLine($"T3 ContinueWith{Thread.CurrentThread.ManagedThreadId}处理业务");
// Thread.Sleep(5000);
//});
var t4 = Task.Run(() =>
{
Console.WriteLine($"T4 开启线程{Thread.CurrentThread.ManagedThreadId}处理业务");
Thread.Sleep(2);
});
// t4.Wait();
List<Task> allTask = new List<Task> {t1,t2,t3,t4 };
//Task.WaitAll(allTask.ToArray());
//Task.WaitAny(allTask.ToArray());
Task.Factory.ContinueWhenAll(allTask.ToArray(),task=>
{
Console.WriteLine("所有子线程都已经完成了");
});
Console.WriteLine($"主线程{Thread.CurrentThread.ManagedThreadId}完成");
Console.ReadLine();
}
delegate void Func();
//函数 fun1
static void fun1()
{
Console.WriteLine("没有参数action");
}
//函数 fun2
static void fun2(object s)
{
Console.WriteLine(s.ToString());
}
public static int F4(object a)
{
Console.WriteLine(a);
return 0;
}
static bool FunWithMultiPara(int i, string s)
{
return i.ToString().Equals(s) ? true : false;
}
static async void AsyncMethond()
{
Console.WriteLine("开始异步代码");
// 异步方法,当使用await 的时候是使用task 的异步任务,否则还是同步执行
var result = await MyMethod();
Console.WriteLine("异步代码执行完毕" + result.ToString());
}
static async Task<int> MyMethod()
{
for (int i = 0; i < 5; i++)
{
Console.WriteLine("异步执行" + i.ToString() + "..");
await Task.Delay(10); //模拟耗时操作
}
return 100;
}
/// <summary>
/// main 方法不能使用 async
/// </summary>
static void Main3()
{
Console.WriteLine("主线程测试开始..");
AsyncMethond();
Thread.Sleep(20000);
Console.WriteLine("主线程测试结束..");
Console.ReadLine();
}
[STAThread]
static void Main1()
{
//----------------------------------------------------------创建------------------------------------------------------------------
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
//-----------------------------------------------------Action 没有返回值类型的委托------------------------------------------------------------------
Func func = fun1;
Task.Factory.StartNew(new Action(func)); // 没有参数
//-----------------------------------------------------Func 没有返回值类型的委托------------------------------------------------------------------
//Func至少0个输入参数,至多16个输入参数,根据返回值泛型返回。必须有返回值,不可void。
//Func<int> 表示没有输入参参,返回值为int类型的委托。
//Func<object, string, int> 表示传入参数为object, string ,返回值为int类型的委托。
//Func<object, string, int> 表示传入参数为object, string, 返回值为int类型的委托。
//Func < T1,T2,,T3,int> 表示传入参数为T1,T2,,T3(泛型),返回值为int类型的委托。
// 没有参数
Func func78787 = delegate ()
{
Console.WriteLine("func78787---------");
};
Task.Run(()=> { func78787(); });
// 只有一个参数
// action<object>
{
Task.Factory.StartNew(fun2, " 只有一个参数 9999999999999999999999");
Task.Run(() => { fun2(" 只有一个参数 88888888888888888888888888 "); });
}
// func 方法 一个参数 有返回值类型的委托
var s = Task<int>.Factory.StartNew(new Func<object, int>(F4),20);
Console.WriteLine(s.Result);
//func委托 返回值
// 在Task 中只显示返回值
//有两个参数 并且有返回值
var niuni=Task<bool>.Factory.StartNew(new Func<bool>(() => FunWithMultiPara(20, "2")));
Console.WriteLine(niuni.Result);
// 第一种方法 使用委托和方法
Task task = new Task(new Action(PringtMsg));
// 使用匿名委托
Task taskdelegate = new Task(delegate
{
Console.WriteLine("hello world taskdelegate");
});
//第二种 使用lamdba 表达式的方法
Task lamdba = new Task(() => PringtMsg2());
// 第三种方式 使用lamdba和匿名方式
Task task_lamdba = new Task(() =>
{
Console.WriteLine("hello world task_lamdba");
});
task.Start();
taskdelegate.Start();
lamdba.Start();
task.ContinueWith((y) => {
Console.WriteLine("任务完成,完成时候的状态为:");
Console.WriteLine("IsCanceled={0}\tIsCompleted={1}\tIsFaulted={2}", y.IsCanceled, y.IsCompleted, y.IsFaulted);
});
task_lamdba.Start();
string[] messages = { "First task", "Second task", "Third task", "Fourth task" };
foreach (var item in messages)
{
Task taskm = new Task((sm) => Print((string)sm), item);
// 第二种方式
Task t1 = new Task(() => Print222(item));
taskm.Start();
t1.Start();
}
//=============================================Task 返回值=====================================================================
Task<int> sum = new Task<int>(() => GetSum());
sum.Start();
Console.WriteLine($"task result is {sum.Result}");
//============================================= Task 返回值 =====================================================================
=============================================传入参数 Task 返回值=====================================================================
Task<double> ta = new Task<double>((i) => GetNum((int)i), 100);
ta.Start();
Console.WriteLine($"ta result is {ta.Result}");
=============================================传入参数 Task 返回值=====================================================================
// ========================================================================================================================
Task<int> factory_tesk = Task.Factory.StartNew<int>((n) =>
{
// 这里的M变量名是不能和上面的重复的
int M = 0;
for (int i = 0; i <= (int)n; i++)
{
M = M + i;
}
return M;
}, 100);
Console.WriteLine($"sum = {factory_tesk.Result}");
// ========================================================================================================================
Thread.Sleep(1100);
Application.Run(new Form1());
Console.Read();
}
private static int F5(object arg1, int arg2)
{
throw new NotImplementedException();
}
private static double GetNum(int len)
{
double sum = 0;
for (int i = 0; i <= len; i++)
{
sum = sum + i;
Thread.Sleep(10);
}
return sum;
}
private static int GetSum()
{
int sum = 0;
for (int i = 0; i <= 10; i++)
{
sum = sum + i;
Thread.Sleep(100);
}
return sum;
}
private static void Print(string msg)
{
Console.WriteLine($"print message : {msg}");
}
private static void Print222(string msg)
{
Console.WriteLine($"print Print222 : {msg}");
}
private static void PringtMsg()
{
Console.WriteLine("hello world");
}
private static void PringtMsg2()
{
Console.WriteLine("hello world2222 ");
}
}
internal class Task<T1, T2, T3>
{
}
}
上一篇: 【C++11】常用新语法①(统一的列表初始化 || initializer_list || 声明 || STL新增容器 || 右值引用和移动语义 || 万能引用和完美转发)
下一篇: 【C++】—— 内存管理
本文标签
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。