Introduction to WPF MaterialDesign sample open source project

零下一度
Release: 2017-06-23 15:01:43
Original
4307 people have browsed it

Hello all, I’m back again

This time we really started to talk about the development ideas of small but useful modules or components in open source projects .

At the same time, the software has been updated to version 1.60, which supports new user registration, and you can no longer use a unified test account.

You can download it through the following path:

1. Fellow the project on GitHub, download it locally, and generate it to get the latest version of the program.

2. Users whose local version is beta v0.5 can directly click Update in the upper right corner of the program

3. The last compressed package for non-Microsoft developers is the following compressed package, which can be directly decompressed. be usable.


If you still don’t know what the software is, you can check out this blog post:

[WPF MaterialDesign sample open source project] Work Time Manager

Today, let’s talk about the client’s log component.

I don’t know if components are appropriate. Anyway, they are small modules that are part of the software and can be reused. I call them components.

This time the log class is a very typical component. The log has many characteristics;

1. It will be used anywhere in the software.

2. It will be used at any time. Being called

3, extremely high usage

4, frequent io operations

When I just came into contact with c# I had used Log4net when I was a child, but the idea that came to my mind at that time was that my program might only be a few meters in size, and a log component would be bigger than my main program. This was obviously inappropriate.

So before I graduated two years ago, I started making my first log component.

[.net] Create your own log component - improved version

The basic idea is still good, including: threads, blocking, resource competition, etc. have been taken into consideration.

As the saying goes, a newborn calf is not afraid of tigers, so he just started doing it without knowing anything.

Written the first version of the log component by opening threads.

However, after all, he is young, and the problem is still obvious. Typing 100 messages in one second will not work.

So when I started C# development again, I took some time to refactor.

First, let’s start with the overall architecture:
- Features of old components:
* Use Multi-thread queue, using mutually exclusive variables to control thread writing of text.
* Control the contention of resources through singleton locking
* Threads are randomly selected to lock, and the log time sequence of writing is May be wrong
* One thread operates one text operation, switches are operated in one thread, and only one variable is written at a time
- Advantages:
* Multi-threaded operation, superficially improving operation efficiency
* Single instance locking to ensure uniqueness
- Disadvantages:
* Low performance, excessive operation of io Leading to severe redundancy in performance
* Only write one item at a time
-Improvement
* Use the producer-consumer model, separate operations, and limit the number of threads
* Use stack queue, first in, first out, to ensure log order
* Single instance IO variable, batch write operations
Transformation results:
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 = 10000;// 10sstatic 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 == 0)
            {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 = 50;var lineNum = LogQueue.Count > onceTime ? onceTime : LogQueue.Count;for (var i = 0; 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);
            }
        }
    }
}
Copy after login

The code does not have the application of third-party components, just copy this file and use it.

We have not dealt with some special situations for the time being, such as log files being occupied, temporary software shutdown, and considerations such as queue trigger time and batch write number. This is just a basic demo,

Of course, if you want to know about subsequent improvements, you can follow the project's GitHub.

Of course, I look forward to your better suggestions. Let’s learn together. If you have a good idea but don’t want to write it yourself, I’ll help you realize it!


The above is the detailed content of Introduction to WPF MaterialDesign sample open source project. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template