(精华)2020年12月23日 .NET Core 多线程底层详解(线程本地存储)
【摘要】
一般来说线程都是有自己上下文,变量是不共享的,这就需要线程本地存储
public static class TlsSample
{
[ThreadStatic]
public stati...
一般来说线程都是有自己上下文,变量是不共享的,这就需要线程本地存储
public static class TlsSample
{
[ThreadStatic]
public static int a;
[ThreadStatic]
public static int b;
public static void Thread1()
{
a = 1;
b = 2;
Console.WriteLine($"a={a} [From Thread1]");
Console.WriteLine($"b={b} [From Thread1]");
}
public static void Thread2()
{
a = 10;
b = 20;
Console.WriteLine($"a={a} [From Thread2]");
Console.WriteLine($"b={b} [From Thread2]");
}
public static void Run()
{
var thread1 = new Thread(Thread1);
var thread2 = new Thread(Thread2);
thread1.Start();
thread2.Start();
}
}
- 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
public class ThreadLocalSample
{
public readonly ThreadLocal<int> a = new ThreadLocal<int>();
public readonly ThreadLocal<int> b = new ThreadLocal<int>();
public void Thread1()
{
a.Value = 1;
b.Value = 2;
Console.WriteLine($"a={a} [From Thread1]");
Console.WriteLine($"b={b} [From Thread1]");
}
public void Thread2()
{
a.Value = 10;
b.Value = 20;
Console.WriteLine($"a={a} [From Thread2]");
Console.WriteLine($"b={b} [From Thread2]");
}
public void Run()
{
var thread1 = new Thread(Thread1);
var thread2 = new Thread(Thread2);
thread1.Start();
thread2.Start();
}
}
- 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
异步本地变量AsyncLocal(执行上下文)
public static class Sample07
{
private static readonly ThreadLocal<int> ThreadLocal = new ThreadLocal<int>();
private static readonly AsyncLocal<int> AsyncLocal = new AsyncLocal<int>();
public static async Task Run()
{
ThreadLocal.Value = 10;
AsyncLocal.Value = 10;
Console.WriteLine($"Tid={Thread.CurrentThread.ManagedThreadId};" +
$"ThreadLocal={ThreadLocal.Value};" +
$"AsyncLocal={AsyncLocal.Value}");
await Task.Delay(1000);
Console.WriteLine($"Tid={Thread.CurrentThread.ManagedThreadId};" +
$"ThreadLocal={ThreadLocal.Value};" +
$"AsyncLocal={AsyncLocal.Value}");
}
}
- 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 Sample08
{
private static readonly AsyncLocal<int> AsyncLocal = new AsyncLocal<int>();
public static async Task ParentTask()
{
AsyncLocal.Value = 111;
Console.WriteLine($"ParentTask Begin:AsyncLocal={AsyncLocal.Value}");
await ChildTask();
Console.WriteLine($"ParentTask End:AsyncLocal={AsyncLocal.Value}");
}
public static async Task ChildTask()
{
Console.WriteLine($"ChildTask Begin:AsyncLocal={AsyncLocal.Value}");
AsyncLocal.Value = 222;
await Task.Delay(1000);
Console.WriteLine($"ChildTask End:AsyncLocal={AsyncLocal.Value}");
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
禁止捕捉执行上下文,则无法传递到其他线程
public static class Sample11
{
private static readonly AsyncLocal<int> AsyncLocal = new AsyncLocal<int>();
public static async Task ParentTask()
{
AsyncLocal.Value = 111;
Console.WriteLine($"ParentTask Begin:AsyncLocal={AsyncLocal.Value}");
// 禁止捕捉执行上下文
var control = ExecutionContext.SuppressFlow();
Task.Delay(100).ContinueWith(task =>
{
Console.WriteLine($"SuppressFlow:AsyncLocal={AsyncLocal.Value}");
});
// 恢复捕捉上下文
control.Undo();
// 捕捉到的执行上下文为null
await Task.Delay(100);
Console.WriteLine($"Undo:AsyncLocal={AsyncLocal.Value}");
}
}
- 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
文章来源: codeboy.blog.csdn.net,作者:愚公搬代码,版权归原作者所有,如需转载,请联系作者。
原文链接:codeboy.blog.csdn.net/article/details/108394662
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)