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>

{

}

}



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。