OSDN Git Service

Device クラスのメンバを若干修正。
[strokestylet/CsWin10Desktop3.git] / FDK24 / Log.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Diagnostics;
4
5 namespace FDK
6 {
7         public class Log
8         {
9                 /// <summary>
10                 /// これを設定しておくと、スレッドID の横に (名前) と出力されるようになる。
11                 /// </summary>
12                 public static void 現在のスレッドに名前をつける( string 名前 )
13                 {
14                         lock( Log.排他 )
15                         {
16                                 var ID = Log.GetCurrentThreadId();
17
18                                 if( Log.IDto名前.ContainsKey( ID ) )
19                                         Log.IDto名前.Remove( ID );
20
21                                 Log.IDto名前.Add( ID, 名前 );
22                         }
23                 }
24
25                 public static void Info( string 出力 )
26                 {
27                         lock( Log.排他 )
28                         {
29                                 Log.一定時間が経過していたら区切り線を表示する();
30                                 Trace.TraceInformation( $"{Log.日時とスレッドID}{Log.インデックスを返す( Log.深さ )}{出力}" );
31                         }
32                 }
33                 public static void ERROR( string 出力 )
34                 {
35                         lock( Log.排他 )
36                         {
37                                 Log.一定時間が経過していたら区切り線を表示する();
38                                 Trace.TraceError( $"{Log.日時とスレッドID} {出力}" );
39                         }
40                 }
41                 public static void WARNING( string 出力 )
42                 {
43                         lock( Log.排他 )
44                         {
45                                 Log.一定時間が経過していたら区切り線を表示する();
46                                 Trace.TraceWarning( $"{Log.日時とスレッドID} {出力}" );
47                         }
48                 }
49                 public static void BeginInfo( string 開始ブロック名 )
50                 {
51                         lock( Log.排他 )
52                         {
53                                 Log.一定時間が経過していたら区切り線を表示する();
54                                 Trace.TraceInformation( $"{Log.日時とスレッドID}{Log.インデックスを返す( Log.深さ )}{開始ブロック名} --> 開始" );
55
56                                 Log.深さ += 4;
57                         }
58                 }
59                 public static void EndInfo( string 終了ブロック名 )
60                 {
61                         lock( Log.排他 )
62                         {
63                                 Log.深さ = Math.Max( ( Log.深さ - 4 ), 0 );
64
65                                 Log.一定時間が経過していたら区切り線を表示する();
66                                 Trace.TraceInformation( $"{Log.日時とスレッドID}{Log.インデックスを返す( Log.深さ )}{終了ブロック名} <-- 終了" );
67                         }
68                 }
69
70                 /// <summary>
71                 /// 連続して呼び出しても、前回の同一識別キーでの表示から一定時間が経たないと表示しないInfoメソッド。
72                 /// </summary>
73                 /// <remarks>
74                 /// 毎秒60回の進行描画の進捗など、連続して呼び出すと膨大な数のログが出力されてしまう場合に使用する。
75                 /// </remarks>
76                 /// <param name="識別キー"></param>
77                 /// <param name="出力"></param>
78                 public static void 定間隔Info( string 識別キー, string 出力, double 間隔sec = 0.25 )
79                 {
80                         lock( Log.排他 )
81                         {
82                                 if( Log.識別キー別最終表示時刻.ContainsKey( 識別キー ) )
83                                 {
84                                         if( ( DateTime.Now - Log.識別キー別最終表示時刻[ 識別キー ] ).TotalSeconds >= 間隔sec )
85                                         {
86                                                 Log.識別キー別最終表示時刻[ 識別キー ] = DateTime.Now;
87                                                 Trace.TraceInformation( $"{Log.日時とスレッドID} {出力}" );
88                                         }
89                                 }
90                                 else
91                                 {
92                                         Log.識別キー別最終表示時刻.Add( 識別キー, DateTime.Now );
93                                         Trace.TraceInformation( $"{Log.日時とスレッドID} {出力}" );
94                                 }
95                         }
96                 }
97
98                 private static string 日時とスレッドID
99                 {
100                         get
101                         {
102                                 var NETスレッドID = System.Threading.Thread.CurrentThread.ManagedThreadId;
103                                 var Win32スレッドID = Log.GetCurrentThreadId();
104                                 var スレッド識別文字列 = ( Log.IDto名前.ContainsKey( Win32スレッドID ) ) ? $"({Log.IDto名前[ Win32スレッドID ]})" : "";
105                                 return $"{DateTime.Now.ToLongTimeString()} [{NETスレッドID:00},0x{Win32スレッドID:x}{スレッド識別文字列}]";
106                         }
107                 }
108                 private static readonly Dictionary<uint, string> IDto名前 = new Dictionary<uint, string>();
109                 private static Dictionary<string, DateTime> 識別キー別最終表示時刻 = new Dictionary<string, DateTime>();
110                 private static TimeSpan 経過時間
111                 {
112                         get
113                         {
114                                 var 現在時刻 = DateTime.Now;
115                                 var 経過時間 = 現在時刻 - Log.最終表示時刻;
116                                 Log.最終表示時刻 = 現在時刻;  // 更新
117                                 return 経過時間;
118                         }
119                 }
120                 private static DateTime 最終表示時刻 = DateTime.Now;
121                 private const double 最小区切り時間 = 2.0; // 区切り線を入れる最小の間隔[秒]。
122                 private static int 深さ = 0;
123                 private static readonly object 排他 = new object();
124
125                 private static void 一定時間が経過していたら区切り線を表示する()
126                 {
127                         if( Log.最小区切り時間 < Log.経過時間.TotalSeconds )
128                                 Trace.TraceInformation( "・・・" );
129                 }
130                 private static string インデックスを返す( int 長さ )
131                 {
132                         string index = " ";
133                         int len = 長さ * 2;
134                         while( 0 < len )
135                         {
136                                 index += "          ".Substring( 0, Math.Min( len, 10 ) );
137                                 len -= 10;
138                         }
139                         return index;
140                 }
141
142                 #region " Win32 API "
143                 //-----------------
144                 [System.Runtime.InteropServices.DllImport( "kernel32.dll" )]
145                 private static extern uint GetCurrentThreadId();
146                 //-----------------
147                 #endregion
148         }
149 }