C# 多线程 同步

线程

进程与线程

看下任务管理器的线程数

1.线程之间可以数据共享
2.线程是切换执行的
在这里插入图片描述
创建线程 第一种方法,无返回值
语法:var task = new Task(…);
注意 task.start() task.Wait()
//说明一下何谓线程共享数据
在这里插入图片描述

  //进程线程
            //创建线程 第一种方法,无返回值
            //var task = new Task(..);
            //注意 task.start() task.Wait()
            //说明一下何谓线程共享数据
            int times = 5000;
            var task1 = new Task(() =>
            {
                for (int i = 0; i < times; i++)
                {
                    Console.Write(".");
                }
            });

            var task2 = new Task(() =>
            {
                for (int i = 0; i < times; i++)
                {
                    Console.Write("-");
                }
            });
            task1.Start();
            task2.Start();

            task2.Wait();
            task2.Wait();
            Console.Read();

创建线程 第二种方法,可有可无 返回值
语法:var tast=Task.Factory.StartNew(…);
注:Task.Result 会阻塞
直接执行,无需Start()

            var task = Task.Factory.StartNew(() => "进程");
            Console.WriteLine(task.Result);

线程上的异常处理方法

方法一

Try 下面的语句,即可捕获

            task.Wait()
            task.Result();
            task.WaitAll()
            task.WaitAny();
      var task = Task.Factory.StartNew(() => throw new ApplicationException("here is an erro")); ;
            try
            {
                task.Wait();
            }
            catch (AggregateException exs)
            {
                foreach (var ex in exs.InnerExceptions)
                {
                    Console.WriteLine(ex.Message);
                }
                
            }

方法二

线程上的异常处理方法二。
使用task.ContinueWith(…)


            var task = Task.Factory.StartNew(() => throw new ApplicationException("here is an erro")); ;
            task.ContinueWith((t) => { Console.WriteLine(t.Exception); },TaskContinuationOptions.OnlyOnFaulted);

并行处理
Parallel.For()
Parallel.ForEach()
PLINQ–x.Asparallel().X

   
        static void Main(string[] args) //主线程 
        {
            var list = new List<int>();
            for (int i = 0; i < 50000000; i++)
            {
                list.Add(i);
            }

            CalcTime(() => list.ForEach(i =>Do(ref i)));
            CalcTime(() => list.AsParallel().ForAll(i => Do(ref i)));
            CalcTime(() => Parallel.ForEach(list,i=> Do(ref i) ));  

            //task2.Wait();
            //task2.Wait();
            Console.Read();
        }
        static void Do(ref int i) {
            i = (int)Math.Abs(Math.Sin((i)));
        }
        static void CalcTime(Action action) {
            Stopwatch sw = new Stopwatch();
            sw.Start();
            action();
            sw.Stop();
            Console.WriteLine(sw.ElapsedMilliseconds);
        }

在这里插入图片描述

同步

作用:
原子性
线程安全
在这里插入图片描述

class Program
    {
        static int Count = 0;
        static void Main(string[] args) //主线程 
        {
            var task1 = new Task(Increment);
            var task2 = new Task(Decrement);
            task1.Start();
            task2.Start();
            Task.WaitAll(task1, task2);
            Console.WriteLine(Count);
            Console.Read();
        }
      static  void Increment() {
            for (int i = 0; i < 5000000; i++)
            {
                Count++;
            }
        }
        static void Decrement() {
            for (int i = 0; i < 5000000; i++)
            {
                Count--;
            }
        }

在这里插入图片描述
使用Lock 关键字
使的操作育有原子性
最佳实践
1.对可变的状态进行同步
2.不更改东西不需要同步
3.多个线程访问同一对象是,必须

class Program
    {
        static int Count = 0;
        private static readonly object Syn = new object();
        static void Main(string[] args) //主线程 
        {
            var task1 = new Task(Increment);
            var task2 = new Task(Decrement);
            task1.Start();
            task2.Start();
            Task.WaitAll(task1, task2);
            Console.WriteLine(Count);
            Console.Read();
        }
      static  void Increment() {
        for (int i = 0; i < 50000000; i++)
           {
             lock (Syn) //锁 
              { 
                Count++; 
               }                
            }
        }
        static void Decrement() {
            for (int i = 0; i < 50000000; i++)
            {
                lock (Syn)
                {
                    Count--;
                }
            }

在这里插入图片描述
原子操作
简单封装
interlocked
在这里插入图片描述

 class Program
    {
        static int Count = 0;
        static void Main(string[] args) //主线程 
        {
            var task1 = new Task(Increment);
            var task2 = new Task(Decrement);
            task1.Start();
            task2.Start();
            Task.WaitAll(task1, task2);
            Console.WriteLine(Count);
            Console.Read();
        }
      static  void Increment() {
        for (int i = 0; i < 50000000; i++)
           {
                Interlocked.Increment(ref Count);             
            }
        }
        static void Decrement() {
            for (int i = 0; i < 50000000; i++)
            {
                Interlocked.Decrement(ref Count);
            }
        }

IOC控制反转/DIP 依赖倒置
说白了,面向接口编程…
以来抽象的世界,很美妙…
随后举例–策略模式
先不面相接口,再面向接口

class Button {
            public void On() {
                Console.WriteLine("On");
            }
            public void Off()
            {
                Console.WriteLine("Off");
            }
        }
        class Lamp {
            private Button button = new Button();//has-a
            public void on() { button.On(); }
            public void Off() { button.Off(); }
        }
 interface IButton {
        void On();
        void Off();
    }

    class Program
    {
        class Button: IButton
        {
            public void On() {
                Console.WriteLine("On");
            }
            public void Off()
            {
                Console.WriteLine("Off");
            }
        }
        class Lamp {
            private IButton button;

            public Button Button { get; set; }

            public void on() { button.On(); }
            public void Off() { button.Off(); }
        }
        static void Main(string[] args) //主线程 
        {
            var lamp = new Lamp() { Button = new Button() };
           ;
            Console.WriteLine(Guid.NewGuid().ToString("D"));
        }
     
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值