zoukankan      html  css  js  c++  java
  • 线程同步

    >>返回《C# 并发编程》

    同步的类型主要有两种: 通信数据保护

    1. 阻塞锁

    class LockClass
    {
        // 这个锁会保护 _value。
        private readonly object _mutex = new object();
        private int _value;
        public void Increment()
        {
            lock (_mutex)
            {
                _value = _value + 1;
            }
        }
    } 
    

    锁的使用,有四条重要的规则。

    • 限制锁的作用范围。
    • 文档中写清锁保护的内容。
    • 锁范围内的代码尽量少。
    • 在控制锁的时候绝不运行随意的代码

    2. 异步锁

    class SemaphoreSlimClass
    {
        // 这个锁保护 _value。
        private readonly SemaphoreSlim _mutex = new SemaphoreSlim(1);
        private int _value;
        public async Task DelayAndIncrementAsync()
        {
            await _mutex.WaitAsync();
            try
            {
                var oldValue = _value;
                await Task.Delay(TimeSpan.FromSeconds(oldValue));
                _value = oldValue + 1;
            }
            finally
            {
                _mutex.Release();
            }
        }
    }
    

    规则在这里也同样适用

    • 限制锁的作用范围。
    • 文档中写清锁保护的内容。
    • 锁范围内的代码尽量少。
    • 在控制锁的时候绝不运行随意的代码

    3. 阻塞信号

    class ManualResetEventSlimClass
    {
        private readonly ManualResetEventSlim _initialized = new ManualResetEventSlim();
        private int _value;
        public int WaitForInitialization()
        {
            _initialized.Wait();
            return _value;
        }
        public void InitializeFromAnotherThread()
        {
            _value = 13;
            _initialized.Set();
        }
    }
    

    如果 ManualResetEventSlim 不能满足需求,还可考虑用 AutoResetEventCountdownEventBarrier

    比喻:

    • ManualResetEventSlim 的整个工作方法有点像人群通过大门
    • AutoResetEvent 事件像一个旋转门,一次只允许一人通过。

    4. 异步信号

    class TaskCompletionSourceClass
    {
        private readonly TaskCompletionSource<object> _initialized = new TaskCompletionSource<object>();
        private int _value1;
        private int _value2;
        public async Task<int> WaitForInitializationAsync()
        {
            await _initialized.Task;
            return _value1 + _value2;
        }
        public void Initialize()
        {
            _value1 = 13;
            _value2 = 17;
            _initialized.TrySetResult(null);
        }
    }
    

    信号是一种通用的通知机制

    • 如果这个“信号”是一个用来在代码段之间发送数据的消息,那就考虑使用生产者/消费者队列
    • 不要让通用的信号只是用来协调对共享数据的访问,那种情况下,可使用锁。

    5. 限流

    class MaxDegreeClass
    {
        //工作流限流
        IPropagatorBlock<int, int> DataflowMultiplyBy2()
        {
            var options = new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 10 };
            return new TransformBlock<int, int>(data => data * 2, options);
        }
    
        // 使用 PLINQ
        IEnumerable<int> ParallelMultiplyBy2(IEnumerable<int> values)
        {
            return values.AsParallel()
            .WithDegreeOfParallelism(10)
            .Select(item => item * 2);
        }
    
        // 使用 Parallel 类
        void ParallelRotateMatrices(IEnumerable<Action<float>> matrices, float degrees)
        {
            var options = new ParallelOptions { MaxDegreeOfParallelism = 10 };
            Parallel.ForEach(matrices, options, matrix => matrix.Invoke(degrees));
        }
    
        //并发性异步代码可以用 SemaphoreSlim 来限流:
        async Task<string[]> DownloadUrlsAsync(
            IEnumerable<string> urls)
        {
            var httpClient = new HttpClient();
            var semaphore = new SemaphoreSlim(10);
            var tasks = urls.Select(async url =>
            {
                await semaphore.WaitAsync();
                try
                {
                    return await httpClient.GetStringAsync(url);
                }
                finally
                {
                    semaphore.Release();
                }
            }).ToArray();
            return await Task.WhenAll(tasks);
        }
    }
    
  • 相关阅读:
    ASP.NET Core应用程序容器化、持续集成与Kubernetes集群部署(二)
    ASP.NET Core应用程序容器化、持续集成与Kubernetes集群部署(一)
    2018年9月15日上海MVP线下技术交流活动简报
    在.NET中使用机器学习API(ML.NET)实现化学分子式数据格式的判定
    使用Roslyn的C#语言服务实现UML类图的自动生成
    ASP.NET Core应用程序的参数配置及使用
    微软最有价值专家(Microsoft MVP)项目经验分享
    漫谈单体架构与微服务架构(上):单体架构
    ASP.NET Core Web API下事件驱动型架构的实现(五):在微服务中使用自我监听模式保证数据库更新与消息派发的可靠性
    使用C#读写结构化的二进制文件
  • 原文地址:https://www.cnblogs.com/BigBrotherStone/p/12249517.html
Copyright © 2011-2022 走看看