锁Monitor.TryEnter

using HRS.Lib.Comm.Logging;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using HRS.Lib.Comm.Enums;
using HRS.Lib.Comm.Exceptions;

namespace HRS.Service.BLL.Sys.Bill
{
    /// <summary>
    /// 计算费用加锁
    /// </summary>
    public static class BillCalucateFeeBusiness
    {
        #region Property
        // 月账单费用
        private static BillLockObject _NewBillMonthlySocial_ID = new BillLockObject();    // 单个最新ID
        private static BillLockObject _NewBillMonthlySocial = new BillLockObject() { Value = "CalucateFee" };
        // 同步政策库信息
        private static BillLockObject _PolicyVersionSynchronyNew_ID = new BillLockObject();    // 单个最新ID
        private static BillLockObject _PolicyVersionSynchronyNew = new BillLockObject() { Value = "PolicyVersionSynchronyNew" };
        // 同步参保方案、账户
        private static BillLockObject _AccountSolutionSynchronyNew_ID = new BillLockObject();    // 单个最新ID
        private static BillLockObject _AccountSolutionSynchronyNew = new BillLockObject() { Value = "AccountSolutionSynchronyNew" };
        // 变化数据入账单
        private static BillLockObject _ChangesToMonthlySocial_ID = new BillLockObject();    // 单个最新ID
        private static BillLockObject _ChangesToMonthlySocial = new BillLockObject() { Value = "ChangesToMonthlySocial" };
        // 非标费用入账单
        private static BillLockObject _NonStandChangesToMonthlySocial_ID = new BillLockObject();    // 单个最新ID
        private static BillLockObject _NonStandChangesToMonthlySocial = new BillLockObject() { Value = "NonStandChangesToMonthlySocial" };
        // 疫情算费
        private static BillLockObject _AdjustAccountFee_ID = new BillLockObject();    // 单个最新ID
        private static BillLockObject _AdjustAccountFee = new BillLockObject() { Value = "AdjustAccountFee" };

        // 自动雇员内转
        private static BillLockObject _AdjustToNewInstByAuto_ID = new BillLockObject();    // 单个最新ID
        private static BillLockObject _AdjustToNewInstByAuto = new BillLockObject() { Value = "AdjustToNewInstByAuto" };

        // 年调基数翻新
        private static BillLockObject _YearAdjustToFeedBackNewBase2_ID = new BillLockObject();    // 单个最新ID
        private static BillLockObject _YearAdjustToFeedBackNewBase2 = new BillLockObject() { Value = "_YearAdjustToFeedBackNewBase2" };

        // 政策年调基数翻新
        private static BillLockObject _PolicyYearAdjustToDeclareBase_ID = new BillLockObject();    // 单个最新ID
        private static BillLockObject _PolicyYearAdjustToDeclareBase = new BillLockObject() { Value = "_PolicyYearAdjustToDeclareBase" };

        #endregion

        #region 成员方法
        /// <summary>
        /// 算费加锁功能
        /// 单个和全部机构相互锁,如果单个机构算费先一步锁住_PolicyVersionSynchronyNew,
        /// 可能导致全部机构算费不执行(因为会尝试等待10s,所以出现概率很小)
        /// </summary>
        /// <param name="excuteFun"></param>
        /// <param name="enu"></param>
        /// <param name="date"></param>
        /// <param name="institutionId"></param>
        /// <returns></returns>
        public static bool Lock(Func<DateTime, Guid?, bool> excuteFun, BillLockEnum enu, DateTime date, Guid? institutionId = null)
        {
            var lockTaken = false;              // 单个机构
            var lockTakenAll = false;           // 所有机构
            // 全局变量
            var lockObject = GetInstituionLockObj(enu);
            var lockObjectAll = GetAllInstituionLockObj(enu);
            try
            {
                if (institutionId.HasValue)
                {
                    // 判断单个是否lcok
                    Monitor.TryEnter(string.Intern(lockObjectAll.Value + institutionId.Value), ref lockTaken);   // string.Intern转换为同一个地址
                    if (lockTaken)
                    {
                        // 判断全部是否lock
                        Monitor.TryEnter(string.Intern(lockObjectAll.Value), ref lockTakenAll);
                        if (lockTakenAll)
                        {
                            // 全部解锁
                            Monitor.Exit(string.Intern(lockObjectAll.Value));
                            lockTakenAll = false;
                            lockObject.Value = lockObjectAll.Value + institutionId.Value.ToString();    // 单个锁住标志
                            return excuteFun(date, institutionId);    // 执行单个机构
                        }
                        else
                        {
                            Log4Pack.CurLog.Error(string.Format("因为所有机构正在执行【{1}】,所以当前机构【{0}】未执行", institutionId.Value, enu.GetDescription()));
                        }
                    }
                    else
                    {
                        Log4Pack.CurLog.Error(string.Format("因为机构【{0}】正在执行【{1}】,所以当前机构未执行", institutionId.Value, enu.GetDescription()));
                    }
                }
                else
                {
                    // 判断全部是否lock
                    Monitor.TryEnter(string.Intern(lockObjectAll.Value), ref lockTakenAll);
                    if (lockTakenAll)
                    {
                        // 单个可能被lock
                        if (!string.IsNullOrEmpty(lockObject.Value))
                        {
                            // 判断单个有没有被锁(无限期等待)
                            Monitor.TryEnter(string.Intern(lockObject.Value), -1, ref lockTaken);
                            if (lockTaken)
                            {
                                // 等待单个机构被锁住释放
                                Monitor.Exit(string.Intern(lockObject.Value));
                                lockTaken = false;
                                Thread.Sleep(10000); // 等待10s(确保所有单个机构执行完毕)
                                return excuteFun(date, institutionId);       // 执行全部机构
                            }
                        }
                        else
                        {
                            Thread.Sleep(10000); // 等待10s(确保所有单个机构执行完毕)
                            return excuteFun(date, institutionId);
                        }
                    }
                    else
                    {
                        Log4Pack.CurLog.Error(string.Format("因为所有机构正在执行【{0}】,所以所有机构未执行", enu.GetDescription()));
                    }
                }
                return true; // 被锁住,退出不执行
            }
            catch (Exception ex)
            {
                Log4Pack.CurLog.Error(ex.StackTrace);
                var msg = ex.Message;
                if (ex.InnerException != null)
                {
                    msg = ex.InnerException.Message;
                }
                Log4Pack.CurLog.Error("错误明细:" + msg);
                return true;
            }
            finally
            {
                try
                {
                    if (lockTakenAll)
                    {
                        Monitor.Exit(string.Intern(lockObjectAll.Value));
                    }
                    if (lockTaken)
                    {
                        lockObject.Value = "";
                        Monitor.Exit(string.Intern(lockObjectAll.Value + institutionId.Value));
                    }
                }
                catch (Exception ex)
                {
                    Log4Pack.CurLog.Error(ex.StackTrace);
                    var msg = ex.Message;
                    if (ex.InnerException != null)
                    {
                        msg = ex.InnerException.Message;
                    }
                    Log4Pack.CurLog.Error("错误明细:" + msg);
                }
            }
        }
        #endregion

        #region 私有方法
        /// <summary>
        /// 获取所有机构LockObject
        /// </summary>
        /// <param name="enu"></param>
        /// <returns></returns>
        private static BillLockObject GetAllInstituionLockObj(BillLockEnum enu)
        {
            switch (enu)
            {
                case BillLockEnum.NewBillMonthlySocial:
                    {
                        return _NewBillMonthlySocial;
                    }
                case BillLockEnum.PolicyVersionSynchrony:
                    {
                        return _PolicyVersionSynchronyNew;
                    }
                case BillLockEnum.AccountSolutionSynchrony:
                    {
                        return _AccountSolutionSynchronyNew;
                    }
                case BillLockEnum.ChangesToMonthlySocial:
                    {
                        return _ChangesToMonthlySocial;
                    }
                case BillLockEnum.NonStandChangesToMonthlySocial:
                    {
                        return _NonStandChangesToMonthlySocial;
                    }
                case BillLockEnum.AdjustAccountFee:
                    {
                        return _AdjustAccountFee;
                    }
                case BillLockEnum.AdjustToNewInstByAuto:
                    {
                        return _AdjustToNewInstByAuto;
                    }
                case BillLockEnum.YearAdjustToFeedBackNewBase2:
                    {
                        return _YearAdjustToFeedBackNewBase2;
                    }break;
                case BillLockEnum.PolicyYearAdjustToDeclareBase:
                    {
                        return _PolicyYearAdjustToDeclareBase;
                    }break;
                default:
                    throw new ShowInfoException("AllLockObjeck枚举不存在");
            }
        }

        /// <summary>
        /// 获取单个机构LockObject
        /// </summary>
        /// <param name="enu"></param>
        /// <returns></returns>
        private static BillLockObject GetInstituionLockObj(BillLockEnum enu)
        {
            switch (enu)
            {
                case BillLockEnum.NewBillMonthlySocial:
                    {
                        return _NewBillMonthlySocial_ID;
                    }
                case BillLockEnum.PolicyVersionSynchrony:
                    {
                        return _PolicyVersionSynchronyNew_ID;
                    }
                case BillLockEnum.AccountSolutionSynchrony:
                    {
                        return _AccountSolutionSynchronyNew_ID;
                    }
                case BillLockEnum.ChangesToMonthlySocial:
                    {
                        return _ChangesToMonthlySocial_ID;
                    }
                case BillLockEnum.NonStandChangesToMonthlySocial:
                    {
                        return _NonStandChangesToMonthlySocial_ID;
                    }
                case BillLockEnum.AdjustAccountFee:
                    {
                        return _AdjustAccountFee_ID;
                    }
                case BillLockEnum.AdjustToNewInstByAuto:
                    {
                        return _AdjustToNewInstByAuto_ID;
                    }
                case BillLockEnum.YearAdjustToFeedBackNewBase2:
                    {
                        return _YearAdjustToFeedBackNewBase2_ID;
                    } break;
                case BillLockEnum.PolicyYearAdjustToDeclareBase:
                    {
                        return _PolicyYearAdjustToDeclareBase_ID;
                    } break;
                default:
                    throw new ShowInfoException("SingleLockObjeck枚举不存在");
            }
        }
        #endregion
    }

    #region 辅助类、枚举
    /// <summary>
    /// 账单参数枚举
    /// </summary>
    public enum BillLockEnum
    {
        /// <summary>
        /// 月账单作业
        /// </summary>
        [DefaultValue("0")]
        [Description("月账单作业")]
        NewBillMonthlySocial = 0,
        /// <summary>
        /// 同步政策库信息
        /// </summary>
        [DefaultValue("1")]
        [Description("同步政策库信息")]
        PolicyVersionSynchrony,
        /// <summary>
        /// 参保方案,账户变动同步
        /// </summary>
        [DefaultValue("2")]
        [Description("参保方案,账户变动同步")]
        AccountSolutionSynchrony,
        /// <summary>
        /// 变化数据入账单
        /// </summary>
        [DefaultValue("3")]
        [Description("变化数据入账单")]
        ChangesToMonthlySocial,
        /// <summary>
        /// 非标费用入账单
        /// </summary>
        [DefaultValue("4")]
        [Description("非标费用入账单")]
        NonStandChangesToMonthlySocial,
        /// <summary>
        /// 疫情算费
        /// </summary>
        [DefaultValue("5")]
        [Description("疫情算费")]
        AdjustAccountFee,

        /// <summary>
        /// 自动雇员内转
        /// </summary>
        [DefaultValue("5")]
        [Description("自动雇员内转")]
        AdjustToNewInstByAuto,

        /// <summary>
        /// 自动雇员内转
        /// </summary>
        [DefaultValue("6")]
        [Description("年调基数翻新")]
        YearAdjustToFeedBackNewBase2,

        /// <summary>
        /// 自动雇员内转
        /// </summary>
        [DefaultValue("7")]
        [Description("政策库年调基数翻新")]
        PolicyYearAdjustToDeclareBase
    }
    /// <summary>
    /// 账单Lock对象
    /// </summary>
    public class BillLockObject
    {
        public string Value { get; set; }
    }
    #endregion
}

 

posted @ 2020-10-14 16:26  江境纣州  阅读(165)  评论(0编辑  收藏  举报