C#任务同步

using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using static System.Console;


//任务同步
//1.lock 锁定一个引用类型的变量
/*死锁
    lock (_s1)
    {
        lock (_s2)
        {}
    } 

     lock (_s2)
    {
        lock (_s1)
        {}
    } 
*/
//2.Interlocked类,更快但只支持少数几种的操作
//public int State
//{
//    get
//    {
//        lock (this)
//        {
//            return ++_state;
//        }
//    }
//}
//相当于
//public int State
//{
//    get
//    {
//        return Interlocked.Increment(ref _state);
//    }
//}

//3.Monitor类
//4.SpinLock结构,传递时需加引用,不然结构会以值传递
//  如果有大量锁定,如列表的每一个节点都有一个锁定,且锁定时间非常短,SpinLock结构就很有用
//  它与Monitor类似,Enter TryEnter Exit

//5.WaitHandle 抽象基类 用于等待一个信号(WaitOne() WaitAll() ...)
//6.Mutex类 操作系统能识别有名称的互斥,可以跨线程,如果没有指定名称则不在不同的进程之间共享
//7.Semaphore类 非常类似于互斥,区别是它可以同时由多个线程使用,是一种计数的互斥
//8.Event类 事件与互斥和信号量一样,也是一个系统范围内的资源同步方法
//      ManualResetEvent  AutoResetEvent ManualResetEventSlim CountdownEvent
//9.Barrier类 ReaderWriterLockSlim类

//10.Timer类
//     Threading中的Timer 基于XAML应用程序的DispatcherTimer

namespace ConsoleApp
{
    public class StateObject
    {
        private int _state = 5;
        private object _sync = new object();
        
        public void ChangeState(int loop)
        {
            
            lock (_sync)//方法2.
            {
                if (_state == 5)
                {
                    _state++;
                    Trace.Assert(_state == 6,
                        $"Race condition occured after {loop} loops");
                }
                _state = 5;
            }
        }

    }
    class Program
    {
        static void Main(string[] args)
        {
            //RaceCondition();

            object o = new object();
            lock (o) { }
            //lock由编译器解析为Monitor类
            Monitor.Enter(o);
            try { }
            finally { Monitor.Exit(o); }

            //Monitor可以设置等待时间
            bool _lockTaken = false;
            Monitor.TryEnter(o, 500, ref _lockTaken);
            if (_lockTaken)//get the lock
            {
                try { }
                finally { Monitor.Exit(o); }
            }
            else { }


            //互斥
            bool createNew;
            //第3个为输出参数,接收一个表示互斥是否为新建的布尔值,
            //如果(createNew)返回为false就表示互斥已经定义
            var mutex = new Mutex(false, "ProCSharpMutex", out createNew);

            if (mutex.WaitOne())
            {
                try { }
                finally { mutex.ReleaseMutex(); }
            }
            else
            {
                //some problem happened while waiting
            }

            //信号量
            int taskCount = 6;
            int semaphoreCount = 3;
            var semaphore = new Semaphore(semaphoreCount-1, semaphoreCount);//初始请求数 最大请求数
            try
            {
                int preCount = semaphore.Release();
                WriteLine($"preCount: {preCount}");
            }
            catch (Exception) { }

            var tasks = new Task[taskCount];
            for (int i = 0; i < taskCount; ++i)
            {
                tasks[i] = Task.Run(() => TaskMain(semaphore));
            }
            Task.WaitAll(tasks);
            WriteLine("All tasks finished");

            //事件
            AutoResetEvent autoEvent = new AutoResetEvent(false);
            autoEvent.Reset();
            autoEvent.Set();

            autoEvent.WaitOne();

            //Timer
            using (var timer1 = new Timer(TimeAction, null, 0/*TimeSpan.FromSeconds(0)*/, 1000/*TimeSpan.FromSeconds(3)*/))
            {
                Task.Delay(15000).Wait();
            }
            




           ReadKey();
        }


        public static void RaceCondition()
        {
            var state = new StateObject();
            //开启2个Task
            for (int i = 0; i < 2; ++i)
            {
                Task.Run(() =>
                {
                    int j = 0;
                    while (true)
                    {
                        lock (state)//方法1.
                        {
                            state.ChangeState(j++);
                        }
                    }
                });
            }
        }

        public static void TaskMain(Semaphore semaphore)
        {
            bool isComplete = false;
            while(!isComplete)
            {
                if (semaphore.WaitOne(50))//等到 计数-1
                {
                    try
                    {
                        WriteLine($"Task {Task.CurrentId} locks the semaphore");
                        Task.Delay(200).Wait();
                    }
                    finally
                    {
                        WriteLine($"Task {Task.CurrentId} release the semaphore");
                        semaphore.Release(); //释放 计数+1
                        isComplete = true;
                    }
                }
                else
                {
                    WriteLine($"Timeoue for task {Task.CurrentId}; wait again");
                }
            }
        }

        private static void TimeAction(object o)
        {
            WriteLine($"System.Threading.Timer {DateTime.Now:T}");
        }

       
    }
}

 

posted @ 2018-09-07 00:16  xslwm  阅读(353)  评论(0编辑  收藏  举报