Hello all , 我又回来了

这次我们真是开始来聊聊开源项目里,小而有用的模块或者组件的开发思想。

同时,软件已经更新到1.60的版本了,支持新用户注册,可以不再使用统一的test账户了。

您可以通过以下路径进行下载:

1、在GitHub上fellow一下项目,下载到本地,生成一下,即可获取最新版程序。

2、本地是beta v0.5版本的用户可以直接在程序右上角点击更新

3、最后给非微软系开发者的是以下的压缩包,直接解压即可使用。

【点击下载】

如果你还不知道是什么软件,可以查看这篇博文:

【WPF MaterialDesign 示例开源项目】 Work Time Manager

今天,我们聊聊客户端的日志组件。

我也不知道说组件合不合适,反正就是属于软件一部分并且可以被重复利用的小模块我称之为组件。

这次的日志类就是很典型的一个组件,日志有很多特点;

1、会被使用在软件的任意一个地方

2、随时都会被调用

3、使用率极高

4、频繁的io操作

在我刚刚接触c#的时候,就使用过了Log4net,但是,那时候就萌生的想法是,我一个程序可能也才几m大小,一个日志组件就比上我一个主程序了,这明显是不合适的。

于是两年前还没有毕业的我着手做了自己的第一个日志组件。

【.net】创建属于自己的log组件——改进版

基础的思想还是好的,包括:线程,阻塞,资源竞争等都做了一定的考虑。

俗话说初生牛犊不怕虎,啥也不太知道的自己就这么开干了。

写了第一版通过开线程来做的日志组件。

可是,毕竟年轻,问题还是显而易见的。一秒打100条就不行了。

于是在我重新着手c#开发的时候,抽了点时间,来了一次重构。

首先,从整体架构下手:
 
- 旧组件特点:
    * 使用多线程队列,用互斥变量控制线程对文本的写入。
    * 通过单例加锁的方式,控制资源的争夺
    * 线程是随机被选中入锁的,写入的日志时间顺序可能不对
    * 一个线程一次文本操作,开关都在一个线程操作,一次只写入一条变量
 
- 优点:
    * 多线程操作,表面提高操作效率
  * 单例加锁,确保唯一
 
- 缺点:
    * 性能底下,过度操作io导致性能严重冗余
    * 一次只写一条
 
- 改进
    * 使用生产者消费者模式,分开操作,限制线程数量
    * 使用栈队列,先进先出,保证日志顺序
    * 单例IO变量,批量进行写入操作
 
改造成果:
using System;
using System.Collections;
using System.IO;
using System.Text;
using System.Threading;
using System.Windows.Threading; namespace Helper
{
public static class LogHelper
{
private static readonly Queue LogQueue = new Queue(); private static bool _isStreamClose = true; private static bool _isThreadBegin = false; private static StreamWriter _fileStreamWriter; private static readonly string fileName =@"BugLog.txt"; static int _intervalTime = ;// 10s static System.Timers.Timer _timer = new System.Timers.Timer(_intervalTime); /// <summary>
/// 添加日志队列
/// </summary>
/// <param name="message"></param>
public static void AddLog(string message)
{
string logContent = $"[{DateTime.Now:yyyy-MM-dd hh:mm:ss}] =>{message}";
LogQueue.Enqueue(logContent);
if (!_isThreadBegin)
{
BeginThread();
}
} public static void AddLog(Exception ex)
{
var logContent = $"[{DateTime.Now:yyyy-MM-dd hh:mm:ss}]错误发生在:{ex.Source},\r\n 内容:{ex.Message}";
logContent += $"\r\n 跟踪:{ex.StackTrace}";
LogQueue.Enqueue(logContent);
if (!_isThreadBegin)
{
BeginThread();
}
} /// <summary>
/// 读取日志队列的一条数据
/// </summary>
/// <returns></returns>
private static object GetLog()
{
return LogQueue.Dequeue();
} /// <summary>
/// 开启定时查询线程
/// </summary>
public static void BeginThread()
{
_isThreadBegin = true; //实例化Timer类,设置间隔时间为10000毫秒; _timer.Interval = _intervalTime; _timer.Elapsed += SetLog; //到达时间的时候执行事件; _timer.AutoReset = true; //设置是执行一次(false)还是一直执行(true); _timer.Enabled = true;
} /// <summary>
/// 写入日志
/// </summary>
private static void SetLog(object source, System.Timers.ElapsedEventArgs e)
{
if (LogQueue.Count == )
{
if (_isStreamClose) return;
_fileStreamWriter.Flush();
_fileStreamWriter.Close();
_isStreamClose = true;
return;
}
if (_isStreamClose)
{
Isexist();
string errLogFilePath = Environment.CurrentDirectory + @"\Log\" + fileName.Trim();
if (!File.Exists(errLogFilePath))
{
FileStream fs1 = new FileStream(errLogFilePath, FileMode.Create, FileAccess.Write);
_fileStreamWriter = new StreamWriter(fs1);
}
else
{
_fileStreamWriter = new StreamWriter(errLogFilePath, true);
}
_isStreamClose = false;
} var strLog = new StringBuilder(); var onceTime = ; var lineNum = LogQueue.Count > onceTime ? onceTime : LogQueue.Count; for (var i = ; i < lineNum; i++)
{
strLog.AppendLine(GetLog().ToString());
} _fileStreamWriter.WriteLine(strLog.ToString()); } /// <summary>
/// 判断是否存在日志文件
/// </summary>
private static void Isexist()
{
string path = Environment.CurrentDirectory + @"\Log\";
if (!File.Exists(path))
{
Directory.CreateDirectory(path);
}
}
}
}

代码没有第三方组件的应用,直接把这个文件复制即可使用。

现在暂时没有对一些特殊情况做处理,例如日志文件被占用、软件临时关闭,以及队列触发时间和批量写入个数等考虑,这只是一个最基础的demo,

当然,如果你想知道后续的改进方法,可以关注该项目的GitHub 。

当然,期待你们更好的建议,大家一起学习,你有好的想法,自己又不想写,我来帮你实现!

欢迎大家狂喷,只有批评才是前进最好的动力!

同时:WorkTimeManager的在线API 即将开放,欢迎各位开发者开发对应的周边应用哦!

敬请关注:http://api.timemanager.online/

Work Time Manager【开源项目】- 创建自己日志组件 2.0重构的更多相关文章

  1. 小程序官网CMS开源项目出炉,Weixin-App-CMS 1.0 版本正式发布

    Weixin-App-CMS 是捷微团队开发的微信小程序CMS开源项目,涵盖了微网站的基本功能,能够快速发布简单易用的小程序网站.采用工具“微信web开发”上传小程序,即可快速体验发布体验小程序网站. ...

  2. 开源项目——小Q聊天机器人V1.0

    小Q聊天机器人V1.0 http://blog.csdn.net/baiyuliang2013/article/details/51386281 小Q聊天机器人V1.1 http://blog.csd ...

  3. 这年头做开源项目,被冷嘲热讽,FreeSql 0.0.4

    FreeSql 项目大概在20天前想着要做的,今天发布0.0.4在群里被一位大神讽刺. 这位无名氏哥们的观点,先声明这不是找安慰的文章,更加不是报复打击的目的. 1 所以这个比EF好在哪里 2 毕竟E ...

  4. 开源项目大全 >> ...

    http://www.isenhao.com/xueke/jisuanji/kaiyuan.php   监控系统-Nagios 网络流量监测图形分析工具-Cacti 分布式系统监视-zabbix 系统 ...

  5. android开源项目学习

    FBReaderJ FBReaderJ用于Android平台的电子书阅读器,它支持多种电子书籍格式包括:oeb.ePub和fb2.此外还支持直接读取zip.tar和gzip等压缩文档. 项目地址:ht ...

  6. GitHub上最受欢迎的Android开源项目TOP20

    以下这些开源项目都是从GitHub上筛选的,我强烈推荐android程序源代码有时间的时候自己在上面淘淘,或许能发现自己须要的开源程序. 了解开源项目有两个优点: 1.借鉴代码,一般来说.火爆的开源项 ...

  7. 打造一个高逼格的android开源项目——小白全攻略 (转)

    转自:打造一个高逼格的android开源项目 小引子 在平时的开发过程中,我们经常会查阅很多的资料,最常参考的是 github 的开源项目.通常在项目的主页面能看到项目的简介和基本使用,并且时不时能看 ...

  8. Android开源项目汇总

    Android很多优秀的开源项目,很多UI组件以及经典的HTTP 访问开源,都能给我们带来一些自己项目的启迪或者引用. 下面简单介绍一下自己收藏的一些项目内容. 项目: Apollo音乐播放器:And ...

  9. ASP.NET Core可视化日志组件使用

    前言 今天站长推荐一款日志可视化组件LogDashboard,可以不用安装第三方进程,只需要在项目中安装相应的Nuget包,添加数行代码,就可以实现拥有带Web页面的日志管理面板,十分nice哦. 下 ...

随机推荐

  1. java获得路径的多种方式

    本文讲解java语言中获得运行时路径的多种方式,包括java项目.java web项目.jar.weblogic等多种场景. 一.this.getClass().getClassLoader().ge ...

  2. nginx源码分析——event模块

    源码:nginx 1.12.0   一.简介      nginx是一款非常受欢迎的软件,具备高性能.模块化可定制的良好特性.之前写了一篇nginx的http模块分析的文章,主要对http处理模块进行 ...

  3. 纯净CentOS7.2 yum源配置与使用yum 安装系统工具net-tools

    本节我们来讲CentOS 的yum 源配置 一.yum 简介 yum,是Yellow dog Updater, Modified 的简称,是杜克大学为了提高RPM 软件包安装性而开发的一种软件包管理器 ...

  4. Sublime 3 如何使用列编辑模式

    前言 作为一名运维人员,文本IDE的列编辑模式对工作效率的提升很大.以前总用UE,觉得UE的列编辑模式设置很人性化(alt+c).后来接触了sublime,个人觉得它的列编辑模式使用对比UE略有差距. ...

  5. ajax获取数据后怎么去渲染到页面?

    $.ajax({ url:"apiAttachmentAction_uploadAttachment.action", type:"post", data:fo ...

  6. OC中Foundation框架之NSDictionary、NSMutableDictionary

    NSDictionary概述 NSDictionary的作用类似:通过一个key ,就能找到对应的value 同样 NSDictionary是不可变的,一旦初始化完毕,里面的内容就无法修改 NSDic ...

  7. Web 版 powerdesigner (Canvas) 技术分享

    演示地址:http://www.netuml.com:8088  <canvas></canvas>是HTML5出现的新标签,像所有的dom对象一样它有自己本身的属性.方法和事 ...

  8. java局部/成员/静态/实例变量

    局部变量和成员变量主要是他们作用域的区别成员变量个是类内部:局部变量是定义其的方法体内部(或者方法体内部的某一程序块内——大括号,主要看定义的位置).另外,成员变量可以不显式初始化,它们可以由系统设定 ...

  9. [js笔记整理]面向对象篇

    一.js面向对象基本概念 对象:内部封装.对外预留接口,一种通用的思想,面向对象分析: 1.特点 (1)抽象 (2)封装 (3)继承:多态继承.多重继承 2.对象组成 (1)属性: 任何对象都可以添加 ...

  10. MySQL 的性能(上篇)—— SQL 执行时间分析

    简介 文中内容均为阅读前辈的文章所整理而来,参考文章已在最后全指明 本文分为上下两篇: 上篇:MySQL 的 SQL 执行时间分析 下篇:MySQL 性能优化 后端开发必然会接触到数据库,数据层的优劣 ...