(精华)2020年12月23日 .NET Core 多线程底层详解(异步发展史)
【摘要】
第一阶段
线程有限多余的会固化到磁盘
public static class Sample01
{
public static void Send(IPAddress address, int...
第一阶段
线程有限多余的会固化到磁盘
public static class Sample01
{
public static void Send(IPAddress address, int port)
{
var tcp = new TcpClient();
try
{
//C10K,10K个客户端,4G,10M,上
tcp.Connect(address, port);
tcp.GetStream().Write(Encoding.ASCII.GetBytes("Hello"));
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
finally
{
tcp.Close();
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
第二阶段
基于回调的异步操作
public static class Sample02
{
public static void Send(IPAddress address, int port)
{
var client = new TcpClient();
// 开始异步连接
client.BeginConnect(address, port, ar =>
{
// 无论成功失败都会调用这个回调
try
{
client.EndConnect(ar);
}
catch (Exception e)
{
Console.WriteLine(e);
client.Close();
}
var bytes = Encoding.ASCII.GetBytes("Hello");
var stream = client.GetStream();
stream.BeginWrite(bytes, 0, bytes.Length, result =>
{
try
{
stream.EndWrite(result);
}
catch (Exception e)
{
Console.WriteLine(e);
}
finally
{
client.Close();
}
},null);
},null);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
第三阶段
Task TPL 任务并行库分离了异步操作与注册回调的处理,async和await
第一种,任务中执行指定的委托(运行时内部的线程池中运行),Run和Factory.StartNew
public class TplSample
{
public static Task SendAsync(IPAddress address, int port)
{
var client = new TcpClient();
// 异步连接
var task = client.ConnectAsync(address, port);
var a = new TaskFactory();
// 异步发送数据
var task1 = task.ContinueWith(t =>
{
var bytes = Encoding.ASCII.GetBytes("Hello");
var stream = client.GetStream();
// 返回一个新的task
// 这里会产生Task<Task>嵌套
// 在外部使用Unwrap方法解包
return stream.WriteAsync(bytes, 0, bytes.Length);
}).Unwrap();
// 异步处理发送结果
var task2 = task1.ContinueWith(t =>
{
if (t.IsFaulted)
{
// 失败
}
else if (t.IsCompleted)
{
// 完成
}
client.Close();
});
return task2;
}
public static void Run(IPAddress address, int port)
{
// 创建1万个Task
var tasks = new Task[10000];
for (var i = 0; i < tasks.Length; i++)
{
// SendAsync 本身就是一个异步方法
tasks[i] = SendAsync(address, port);
}
// 等待所有异步操作执行完成
Task.WaitAll(tasks);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
第二种,承诺对象,Promise,将来对象,Future
public class PromiseSample
{
public static Task ConnectAsync(TcpClient client,IPAddress address, int port)
{
// 创建一个承诺对象,
var promise = new TaskCompletionSource<object>();
// 获取将来对象
var future = promise.Task;
client.BeginConnect(address, port, ar =>
{
try
{
client.EndConnect(ar);
promise.SetResult(null);
}
catch (OperationCanceledException)
{
promise.SetCanceled();
}
catch (Exception ex)
{
promise.SetException(ex);
}
},null);
return future;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
task的异步
public static class ChildTaskSample
{
public static Task Run()
{
// 创建一个父任务
var parent = Task.Factory.StartNew(() =>
{
// 创建子任务1
var child1 = Task.Factory.StartNew(() =>
{
// 子任务1
},TaskCreationOptions.AttachedToParent);
// 创建子任务2
var child2 = Task.Factory.StartNew(() =>
{
// 子任务2
}, TaskCreationOptions.AttachedToParent);
});
// 父任务会等待子任务1和2完成以后在调用回调
// 子任务中发生的异常也会传递到父任务的回调中
return parent;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
async和await
public static class Sample06
{
// async关键字是给编译器看的,我就要为生产状态机
public static async Task SendAsync(IPAddress address, int port)
{
var client = new TcpClient();
try
{
// 异步连接
await client.ConnectAsync(address, port);
// 连接成功后会从这里继续开始执行
// 失败时会抛出异常并在下面的catch块中被捕捉
var bytes = Encoding.ASCII.GetBytes("Hello");
var stream = client.GetStream();
// 异步发送数据
await stream.WriteAsync(bytes, 0, bytes.Length);
// 发送成功后会从这里继续开始执行
// 失败时同样会抛出异常,也在下面的catch块中被捕捉
Console.WriteLine("发送完成");
}
catch (Exception e)
{
Console.WriteLine(e);
}
finally
{
client.Close();
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
备注:其他异步
ValueTask
从数据库随机取一条数据
先从数据库随机获取100条数据,作为将来100次调用的返回结果,每100次调用只有一次会查询数据库,其它99次都是同步完成
文章来源: codeboy.blog.csdn.net,作者:愚公搬代码,版权归原作者所有,如需转载,请联系作者。
原文链接:codeboy.blog.csdn.net/article/details/108412708
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)