• 基础才是重中之重~关于ThreadStatic和Quartz的一点渊源


    回到目录

    ThreadStatic

    ThreadStatic是C#里的一个特性,它可以让你的字段在一个线程里有效,但你不能控制这个字段在何时被回收,即如果声明一个int32的字段为ThreadStatic,然后你为它赋值时为100,那么它什么被恢复成默认值0,我们不得而知,这在开发时,我们可能只有手动将它设为0才行,比较难看,但也没办法,谁让咱们用了ThreadStatic呢,被声明为ThreadStatic之后,已经证明这个字段是静态化的,只不过它是被局限在一个线程内的。

    Quartz

    Quartz是一个任务调度框架,起源于java,它目前被广泛的使用在各种后台处理数据的场合,像一些统计数据,推送数据,消息数据等,它可以大大降低前端服务器的并发压力,并且Quartz的管理界面也有很多,直接nuget安装即可,在这些产品中最知名的应该就是CrystalQuartz了,它可以在WEB界面中管理咱们的JOB项目!

    日志系统Lind.DDD.Logger

    Logger本来是Lind框架的一个日志组件,它是最低层的组件,是其它组件的基础,也被用到其它的业务系统里,而其中一个Quartz组件里,使用Logger时提出了一个问题,就是如何根据job去自动建立日志目录,让每个JOB都有自己的目录,这样在分析日志时还是很有必要的。

    希望看到的结果如图

    测试用的两个Job

       public class Hello_Job : JobBase
        {
    
            protected override void ExcuteJob()
            {
    
                Console.WriteLine("Hello Job方法:" + Thread.CurrentThread.ManagedThreadId);
                Lind.DDD.Logger.LoggerFactory.Instance.Logger_Info("Hello Job日志!");
            }
        }
    
        public class Hi_Job : Lind.DDD.QuartzJob.JobBase
        {
    
            protected override void ExcuteJob()
            {
    
                Console.WriteLine("Hi Job!" + Thread.CurrentThread.ManagedThreadId);
                Lind.DDD.Logger.LoggerFactory.Instance.Logger_Info("Hi Job!");
    
            }
        }

    JobBase做于所有Job的基类存在,它主要有自己的抽象方法和IJob的接口方法,其中抽象方法由字类Job自己去实现,去实现自己的业务逻辑;而IJob方法由Quartz框架去调用,并在方法中自己调用了抽象方法的内容,大致代码如下

        [DisallowConcurrentExecution()]
        public abstract class JobBase : IJob
        {
    
            #region IJob 成员
            /// <summary>
            /// Job主方法
            /// </summary>
            /// <param name="context"></param>
            public void Execute(IJobExecutionContext context)
            {
                Lind.DDD.Logger.LoggerFactory.Instance.SetPath(this.GetType().Name);
                ExcuteJob();
                Console.WriteLine(DateTime.Now.ToString() + "{0}这个Job开始执行", context.JobDetail.Key.Name);
            }
    
            #endregion
    
            /// <summary>
            /// Job具体类去实现自己的逻辑
            /// </summary>
            protected abstract void ExcuteJob();
        }

    日志组件中的字段使用了ThreadStatic

    对日志文件分文件夹存储,主要在日志组件中使用ThreadStatic来实现的,代码主要如下

            /// <summary>
            /// 每个子类初始时都执行基类这个构造,初始化当前路径
            /// </summary>
            public LoggerBase()
            {
                FileUrl = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "LoggerDir");
            }
            /// <summary>
            /// 日志文件地址
            /// 优化级为mvc方案地址,网站方案地址,console程序地址
            /// </summary>
            [ThreadStatic]
            static protected string FileUrl;
           #region ILogger 成员
            public void SetPath(string path)
            {
                if (!string.IsNullOrWhiteSpace(path))
                {
                    FileUrl = FileUrl + "\" + path;
                }
            }
            #endregion

    对于FileLogger这个文件日志实现类来说,它要做的是,在写完文件流之后,要把FileUrl这个字段从新赋值,因为我们不知道这个字符串什么时候被清空!

               lock (objLock)//防治多线程读写冲突
                {
                    using (System.IO.StreamWriter srFile = new System.IO.StreamWriter(filePath, true))
                    {
                        srFile.WriteLine(string.Format("{0}{1}{2}"
                            , DateTime.Now.ToString().PadRight(20)
                            , ("[ThreadID:" + Thread.CurrentThread.ManagedThreadId.ToString() + "]").PadRight(14)
                            , message));
                        srFile.Close();
                        srFile.Dispose();
                    }
                }
                //清除当前的路径
                FileUrl = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "LoggerDir");

    上面的问题,我也是找了很久,因为总是找不到测试不成功的原因,最后想到了ThreadStatic特性的声明周期,算是找到根源了,呵呵!

    建议大家看看C#的《对象的生与死》!

    回到目录

  • 相关阅读:
    201521044091《Java程序设计》第7周学习总结
    201521044091《java程序设计》第四次总结
    201521044091 《java程序设计》第八周学习总结
    201521044091 《Java程序设计》第5周学习总结
    201521044091 《Java程序设计》第2周学习总结
    201521044091 《Java程序设计》第3周学习总结
    MySQL设置字符集CHARACTER SET
    Create My MySQL configuration by Percona
    How to use jQuery to manipulate Cookies
    How to use OpenXml to import xml data to Sql server
  • 原文地址:https://www.cnblogs.com/lori/p/6772862.html
Copyright © 2020-2023  润新知