(精华)2020年12月23日 .NET Core 多线程底层详解(线程本地存储)

举报
愚公搬代码 发表于 2021/10/19 01:11:48 2021/10/19
【摘要】 一般来说线程都是有自己上下文,变量是不共享的,这就需要线程本地存储 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

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。