C# Interlocked的使用

学习来源:《CLR via C by Jeffrey Richter 》第四版,第29章,29.3.2 互锁构造  

   internal class MultiWebRequests
    {
        //这个辅助类协调所有异步操作
        private AsyncCoordinator m_ac = new AsyncCoordinator();
        private Dictionary m_servers = new Dictionary() {
            { "http://www.baidu.com",null},
            { "http://www.baidu1.com",null},
            { "http://www.baidu2.com",null},
        };
        /// 
        /// 结果处理
        /// 
        /// 
        /// 
        public void ComputeResult(string server, Task task) {
            object result;
            if (task.Exception != null)
            {
                //在线程池线程上处理i/o完成
                //在此添加自己    的计算密集型算法
                result = task.Exception.InnerException;
            }
            else {
                result = task.Result.Length;
            }
            //保存结果(exception/sum).指出1个操作完成
            m_servers[server] = result;
            m_ac.JustEnded();
        }

        //调用这个方法指出结果已无关紧要
        public void Cancel() { m_ac.Cancel(); }
        /// 
        /// 所有web服务器都响应后
        /// 
        /// 
        public void AllDone(CoordinationStatus status ) {
            switch (status) {
                case CoordinationStatus.Cancel:
                    Console.WriteLine(" CoordinationStatus.Cancel");
                    break;
                case CoordinationStatus.TimeOut:
                    Console.WriteLine(" CoordinationStatus.TimeOut");
                    break;
                case CoordinationStatus.AllDone:
                    Console.WriteLine(" CoordinationStatus.AllDone");
                    foreach (var item in m_servers)
                    {
                        Console.WriteLine("{0}",item.Key);
                        object result = item.Value;
                        if (result is Exception)
                        {
                            Console.WriteLine("failed due to {0}", result.GetType().Name);
                        }
                        else {
                            Console.WriteLine("{0}",result);
                        }
                    }
                    break;
            }
            
        }
        public MultiWebRequests(Int32 timeout = Timeout.Infinite) {
            //以异步方式一次性发起所有请求
            var httpclient = new HttpClient();
            foreach (var item in m_servers.Keys)
            {
                m_ac.AboutToBegin(1);
                //ContinueWith ,异步后立即调用ContinueWith指定的方法
                httpclient.GetByteArrayAsync(item).ContinueWith(task => { ComputeResult(item, task); });
            }
           //所有的异步请求都完成后调用alldone
            m_ac.AllBegun(AllDone,timeout);

        }


    }
 
  internal sealed class AsyncCoordinator {
        private Int32 m_opCount = 1;//allbegun内部调用justended来递减
        private Int32 m_statusReported = 0;//0=false,1=true
        private Action m_callbck;
        private Timer m_time;
        private void TimeExpired (object o) { ReportStatus(CoordinationStatus.TimeOut); }
        /// 
        /// 该方法必须在发起一个操作之前调用
        /// 
        /// 
        public void AboutToBegin(Int32 opsToAdd = 1) {
            Interlocked.Add(ref m_opCount, opsToAdd);  //m_opCount=m_opCount+opsToAdd
        }
        /// 
        /// 该方法必须处理好一个操作的结果后调用
        /// 
        public void JustEnded() {
            //(m_opCount=m_opCount-1)==0
            if (Interlocked.Decrement(ref m_opCount) == 0) {
                ReportStatus(CoordinationStatus.AllDone);
            }

        }
        /// 
        /// 该方法必须在发起所有操作之后调用
        /// 
        /// 
        /// 
        public void AllBegun(Action callback,Int32 timeout=Timeout.Infinite) {
            m_callbck = callback;//AllDone
            if (timeout != Timeout.Infinite) {
                m_time = new Timer(TimeExpired, null, timeout, Timeout.Infinite);
            }
            JustEnded();
        }
        public void Cancel() {
            ReportStatus(CoordinationStatus.Cancel);
        }
        public void ReportStatus(CoordinationStatus status) {
            //第一个进来的线程先获取值0,后修改为1
            if (Interlocked.Exchange(ref m_statusReported, 1) == 0) {
                m_callbck(status);//AllDone(CoordinationStatus status )
            }
        }
    }
  internal enum CoordinationStatus
    {
        AllDone,
        TimeOut,
         Cancel ,
    }

 

 

你可能感兴趣的:(c#,开发语言)