Maison  >  Article  >  développement back-end  >  Introduction à l'exemple de projet open source WPF MaterialDesign

Introduction à l'exemple de projet open source WPF MaterialDesign

零下一度
零下一度original
2017-06-23 15:01:434304parcourir

Bonjour à tous, je suis de retour

Cette fois, nous avons vraiment commencé à parler des idées de développement de modules ou de composants petits mais utiles en open source projets .

Dans le même temps, le logiciel a été mis à jour vers la version 1.60, qui prend en charge l'enregistrement de nouveaux utilisateurs, et vous ne pouvez plus utiliser de compte de test unifié.

Vous pouvez le télécharger via le chemin suivant :

1. Partagez le projet sur GitHub, téléchargez-le localement, générez-le et vous pourrez obtenir la dernière version de le programme.

2. Les utilisateurs qui exécutent la version bêta v0.5 peuvent directement cliquer sur Mettre à jour dans le coin supérieur droit du programme

3 Le package final pour les développeurs non Microsoft est le suivant compressé. package, qui peut être directement décompressé disponible.


Si vous ne savez toujours pas ce qu'est le logiciel, vous pouvez consulter cet article de blog :

[Exemple de projet open source WPF MaterialDesign] Travail Time Manager

Aujourd'hui, nous parlons du composant log du client.

Je ne sais pas si les composants sont appropriés. Quoi qu'il en soit, ce sont des petits modules qui font partie du logiciel et qui peuvent être réutilisés.

Cette fois, la classe de journal est un composant très typique. Le journal a de nombreuses caractéristiques

1 Sera utilisé n'importe où dans le logiciel

2.

3. Utilisation extrêmement élevée

4. Opérations io fréquentes

Quand je viens d'entrer en contact avec c#, j'ai eu J'utilisais Log4net quand j'étais enfant, mais l'idée qui m'est venue à l'esprit à ce moment-là était que mon programme ne mesurerait peut-être que quelques mètres et qu'un composant de journal serait plus grand que mon programme principal. C'était évidemment inapproprié.

Ainsi, avant d'obtenir mon diplôme il y a deux ans, j'ai commencé à fabriquer mon premier composant de bûche.

[.net] Créez votre propre composant de journal - version améliorée

L'idée de base est toujours bonne, notamment : les fils de discussion, le blocage, la concurrence entre les ressources, etc. ont été pris en compte.

Comme le dit le proverbe, un veau nouveau-né n'a pas peur des tigres, alors il a juste commencé à le faire sans rien savoir.

Écrit la première version du composant log en ouvrant des threads.

Cependant, après tout, il est jeune et le problème est toujours évident. Taper 100 messages en une seconde ne fonctionnera pas.

Alors, quand j'ai recommencé le développement en C#, j'ai pris le temps de refactoriser.

Tout d'abord, commencez par l'architecture globale :
- Caractéristiques des anciens composants :
* Utilisez la file d'attente multithread, en utilisant des variables mutuellement exclusives pour contrôler l'écriture du texte par thread.
* Contrôlez les conflits de ressources grâce au verrouillage singleton
* Les threads sont sélectionnés au hasard pour le verrouillage et la séquence temporelle écrite du journal est peut-être erronée
* Un thread effectue une opération de texte, les commutateurs sont actionnés dans un seul thread et une seule variable est écrite à la fois
- Avantages :
* Fonctionnement multithread, améliorant superficiellement l'efficacité opérationnelle
* Verrouillage d'instance unique pour garantir l'unicité
- Inconvénients :
* Faibles performances, fonctionnement io excessif Conduisant à une redondance sévère dans les performances
* N'écrire qu'un seul morceau à la fois
- Amélioration
* Utiliser le modèle producteur-consommateur, opérations séparées , et limitez le nombre de threads
* Utilisez la file d'attente de pile, premier entré, premier sorti pour garantir l'ordre des journaux
* Variable IO à instance unique, opérations d'écriture par lots
Résultats de la transformation :
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);
            }
        }
    }
}

Le code n'a pas l'application de composants tiers, copiez simplement ce fichier et utilisez-le.

Nous n'avons pas traité certaines situations particulières pour le moment, telles que l'occupation des fichiers journaux, l'arrêt temporaire du logiciel et des considérations telles que le temps de déclenchement de la file d'attente et le numéro d'écriture par lots. Ceci est juste une démo de base, <.>

Bien sûr, si vous souhaitez connaître les améliorations ultérieures, vous pouvez suivre le GitHub du projet.

Bien sûr, j'attends avec impatience vos meilleures suggestions et apprenons ensemble. Si vous avez une bonne idée mais que vous ne voulez pas l'écrire vous-même, je vous aiderai à la réaliser. !


Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn