WPF MaterialDesign サンプル オープン ソース プロジェクトの紹介

零下一度
リリース: 2017-06-23 15:01:43
オリジナル
4307 人が閲覧しました

こんにちは、また戻ってきました

今回は、オープンソースプロジェクトにおける小さいながらも有用なモジュールやコンポーネントの開発アイデアについて本格的に話し合い始めました。

同時に、ソフトウェアは新規ユーザー登録に対応したバージョン1.60にアップデートされ、統合テストアカウントは使用できなくなりました。

次のパスからダウンロードできます:

1. GitHub でプロジェクトをフォローし、ローカルにダウンロードして生成すると、プログラムの最新バージョンを入手できます。

2. ローカル バージョンがベータ版 v0.5 であるユーザーは、プログラムの右上隅にある [更新] を直接クリックできます

3. 最後に、次の圧縮パッケージが Microsoft 以外の開発者に提供されており、解凍後に直接使用できます。 。


まだそれが何のソフトウェアなのかわからない場合は、次のブログ投稿をチェックしてください:

[WPF MaterialDesign サンプル オープン ソース プロジェクト] Work Time Manager

今日は、クライアントについて話します。サイドログコンポーネント。

コンポーネントが適切かどうかはわかりませんが、ソフトウェアの一部であり、再利用できる小さなモジュールです。

今回のログ クラスは非常に典型的なコンポーネントです。

1. ソフトウェアのどこでも使用されます。

3. 使用率は次のとおりです。非常に高い

4. 頻繁な io 操作

私が初めて C# に触れたとき、私は Log4net を使用しましたが、その時に頭に浮かんだのは、自分のプログラムはほんの数メートルかもしれないということでした。サイズ的には、ログコンポーネントで十分です。私のメインプログラムと比較すると、これは明らかに不適切です。

そこで、2 年前に卒業する前に、最初のログ コンポーネントを作成し始めました。

【.net】独自のログコンポーネントを作成する - 改良版

基本的なアイデアは依然として優れており、スレッド、ブロッキング、リソース競合などが考慮されています。

「生まれたばかりの子牛はトラを怖がらない」という諺の通り、何も知らずに始めたばかりです。

スレッドを開いてログコンポーネントの最初のバージョンを作成しました。

しかし、結局のところ、私は若いので、問題はまだ明らかです。 1 秒間に 100 件のメッセージを入力しても機能しません。

それで、C# 開発を再開したとき、リファクタリングに少し時間をかけました。

まず全体的なアーキテクチャから始めましょう:

- 古いコンポーネントの機能:
* マルチスレッドキューを使用し、スレッドのテキスト書き込みを制御するためにミューテックス変数を使用します。

* シングルトンロックを通じてリソースの競合を制御します
* スレッドはロックのためにランダムに選択され、書き込まれたログ時間の順序が間違っている可能性があります
* 1 つのスレッドは 1 つのテキスト操作を実行し、スイッチはすべて1 つのスレッド操作で、一度に 1 つの変数のみを書き込みます
- 利点:
* マルチスレッド操作、表面的には操作効率が向上します
、IO の過剰な操作は深刻なパフォーマンスの冗長性につながります
* 1 つの部分のみを書き込みます一度に
- 改善
* プロデューサーコンシューマーモードを使用し、個別の操作を行い、スレッド数を制限します
* スタックキューを使用し、先入れ先出し、保証されたログシーケンスを使用します
* 単一インスタンスの 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 = 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);
            }
        }
    }
}
ログイン後にコピー
コードにはサードパーティ コンポーネントのアプリケーションが含まれていないため、このファイルをコピーして使用するだけです。
今のところ、ログ ファイルの占有、ソフトウェアの一時的なシャットダウン、キューのトリガー時間やバッチ書き込み数などの考慮事項など、いくつかの特殊な状況には対処していません。これは単なる基本的なデモです。
もちろん、後で改善する方法がわかっている場合は、プロジェクトの GitHub をフォローしてください。

もちろん、私はあなたのより良い提案を楽しみにしています、そしてあなたが良いアイデアを持っているがそれを自分で書きたくないなら、私はあなたがそれを実現するのを手伝います!

以上がWPF MaterialDesign サンプル オープン ソース プロジェクトの紹介の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート