程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 輔助功能性代碼,研究和記錄代碼。,輔助功能代碼

輔助功能性代碼,研究和記錄代碼。,輔助功能代碼

編輯:C#入門知識

輔助功能性代碼,研究和記錄代碼。,輔助功能代碼


 

C#下面能產生每秒65535個我無重復ID,但是毫無規則可言。

 

 1 private static int id = 0;
 2 
 3         private static int serverID = 1;
 4 
 5         /// <summary>
 6         /// 下面這段代碼在一秒內,只能生產 65535 個操過了生產是會重復ID 的
 7         /// </summary>
 8         /// <returns></returns>
 9         public static long getId()
10         {
11             lock (typeof(string))
12             {
13                 id += 1;
14                 return (serverID & 0xFFFF) << 48 | (DateTime.Now.CurrentTimeMillis() / 1000L & 0xFFFFFFFF) << 16 | id & 0xFFFF;
15             }
16         }

 

 

======================

C#程序單例模式。某些非web程序,需要驗證單例模式,只能開啟一個客戶端。

目前我曉得的方式調用win32API,

static Mutex mutex;

    /// <summary>
    /// 單例模式
    /// </summary>
    /// <param name="strMutex">系統互斥名,任意設置標識就行</param>
    static public void Singleton(string strMutex = "SzExtensions")
    {
        bool createdNew;
        //系統能夠識別有名稱的互斥,因此可以使用它禁止應用程序啟動兩次
        //第二個參數可以設置為產品的名稱:Application.ProductName
        //每次啟動應用程序,都會驗證名稱為SingletonWinAppMutex的互斥是否存在
        mutex = new Mutex(true, strMutex, out createdNew);
        //如果已運行,則在前端顯示
        //createdNew == false,說明程序已運行
        if (!createdNew)
        {
            Process instance = GetExistProcess();
            //如果程序已經啟動,設置為前端顯示
            if (instance != null) { SetForegroud(instance); }
            //退出當前程序
            System.Environment.Exit(0);
        }
    }

    /// <summary>
    /// 查看程序是否已經運行
    /// </summary>
    /// <returns></returns>
    static Process GetExistProcess()
    {
        Process currentProcess = Process.GetCurrentProcess();
        foreach (Process process in Process.GetProcessesByName(currentProcess.ProcessName))
        {
            if ((process.Id != currentProcess.Id) &&
                (Assembly.GetExecutingAssembly().Location == currentProcess.MainModule.FileName))
            {
                return process;
            }
        }
        return null;
    }

    /// <summary>
    /// 使程序前端顯示
    /// </summary>
    /// <param name="instance"></param>
    static void SetForegroud(Process instance)
    {
        IntPtr mainFormHandle = instance.MainWindowHandle;
        if (mainFormHandle != IntPtr.Zero)
        {
            ShowWindowAsync(mainFormHandle, 1);
            SetForegroundWindow(mainFormHandle);
        }
    }

程序啟動的時候創建一個系統互斥量,設置一個互斥量又好名稱就可以。防止程序第二次啟動。

 

在開發WPF或者WF程序的時候,為了方便測試需要打印一些臨時數據。但是打印是一個非常麻煩的事情,不像控制台程序那樣可以直接輸出。非常便利。那麼我們WPF或者WF程序可不可以以打開控制台輸出呢?

網上查詢了一下可以調用win32API實現打開控制台。其實也就是打開程序的一個輸入和輸出流而已。

[DllImport("User32.dll")]
    private static extern bool SetForegroundWindow(IntPtr hWnd);

    [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
    public static extern IntPtr GetForegroundWindow();

    [MethodImpl(MethodImplOptions.ForwardRef), DllImport("user32.dll")]
    private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    [MethodImpl(MethodImplOptions.ForwardRef), DllImport("kernel32.dll")]
    private static extern bool FreeConsole();
    [MethodImpl(MethodImplOptions.ForwardRef), DllImport("Kernel32.dll")]
    private static extern bool AllocConsole();
    [MethodImpl(MethodImplOptions.ForwardRef), DllImport("user32.dll")]
    private static extern IntPtr GetSystemMenu(IntPtr hWnd, IntPtr bRevert);
    [MethodImpl(MethodImplOptions.ForwardRef), DllImport("user32.dll")]
    private static extern bool ShowWindowAsync(IntPtr hwind, int cmdShow);

    [MethodImpl(MethodImplOptions.ForwardRef), DllImport("user32.dll")]
    private static extern IntPtr RemoveMenu(IntPtr hMenu, uint uPosition, uint uFlags);

    private static string ConsoleTitle = string.Empty;

    private static bool flag_console = false;

    private static System.Timers.Timer Console_Timer;

    /// <summary>
    /// 關閉/隱藏控制台 窗體
    /// </summary>
    static public void Console_Hide()
    {
        if (Console_Timer != null)
        {
            Console_Timer.Stop();
        }
        flag_console = false;
        FreeConsole();
    }

    /// <summary>
    /// 顯示控制台,一旦顯示就不會再調用第二次
    /// </summary>
    /// <param name="title">顯示的標題</param>
    /// <param name="withCloseBox">是否移除關閉按鈕,默認值:false 顯示</param>
    /// <param name="isShowThreadCount">在控制台顯示線程數量,默認值:true 顯示</param>
    static public void Console_Show(string title, [MarshalAs(UnmanagedType.U1)] bool withCloseBox, [MarshalAs(UnmanagedType.U1)] bool isShowThreadCount)
    {
        //檢測flag_console,防止調用兩次
        //直接用win32api
        //順便移除窗口
        if (!flag_console)
        {
            flag_console = true;
            AllocConsole();
            Console.Title = title;
            if (withCloseBox)
            {
                RemoveMenu();
            }
            if (isShowThreadCount) { ShowThreadCount(title); }
            else { Console.Title = title; }
        }
    }

    /// <summary>
    /// 移除關閉按鈕
    /// </summary>
    static void RemoveMenu()
    {
        IntPtr mainFormHandle = GetForegroundWindow();
        RemoveMenu(GetSystemMenu(mainFormHandle, IntPtr.Zero), 0xf060, 0);
    }

    /// <summary>
    /// 在控制台title顯示線程量
    /// </summary>
    /// <param name="title"></param>
    public static void ShowThreadCount(string title)
    {
        ConsoleTitle = title;
        Console_Timer = new System.Timers.Timer(200);
        Console_Timer.Elapsed += (obj, e) =>
        {
            int thrads = Process.GetCurrentProcess().Threads.Count;
            int runthreads = 0;
            foreach (ProcessThread item in Process.GetCurrentProcess().Threads) if (item.ThreadState == System.Diagnostics.ThreadState.Running) runthreads++;
            long mem = System.Environment.WorkingSet / 1024 / 1024;
            Console.Title = string.Format("{0} -> 當前內存占用 -> {3} MB -> 當前線程量 -> {1} ->  當前活動線程: -> {2}", ConsoleTitle, thrads, runthreads, mem);
        };
        Console_Timer.Start();
    }

在此加入了,控制台的打開和關閉功能性輔助代碼。並且加入了控制台標題查看內存和線程使用情況。

 

還有一個非常方便的方式打開WPF和WF控制台輸入輸出流的方式。只能臨時使用的辦法。那就是右鍵項目屬性,選擇更改項目類型,把windows應用程序改為控制台程序。可以實現,WPF和WF程序打開控制輸入輸出流。

 

 

日志輔助========================================

日志輔助線程

 1 /**
 2  * 
 3  * @author 失足程序員
 4  * @Blog http://www.cnblogs.com/ty408/
 5  * @mail [email protected]
 6  * @phone 13882122019
 7  * 
 8  */
 9 namespace Sz
10 {
11     /// <summary>
12     /// 線程模型
13     /// </summary>    
14     internal class ThreadModel
15     {
16         public bool IsStop = false;
17         /// <summary>
18         /// ID
19         /// </summary>
20         public int ID;
21 
22         static int StaticID = 0;
23 
24         public ThreadModel(string name)
25         {
26             lock (typeof(ThreadModel))
27             {
28                 StaticID++;
29             }
30             ID = StaticID;
31             System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(Run));
32             thread.Name = name;
33             thread.IsBackground = true;
34             thread.Start();
35         }
36 
37         /// <summary>
38         /// 任務隊列
39         /// </summary>
40         protected System.Collections.Concurrent.ConcurrentQueue<TaskBase> taskQueue = new System.Collections.Concurrent.ConcurrentQueue<TaskBase>();
41 
42         /// <summary>
43         /// 加入任務
44         /// </summary>
45         /// <param name="t"></param>
46         public virtual void AddTask(TaskBase t)
47         {
48             taskQueue.Enqueue(t);
49             ///防止線程正在阻塞時添加進入了新任務
50             are.Set();
51         }
52 
53         //通知一個或多個正在等待的線程已發生事件
54         protected ManualResetEvent are = new ManualResetEvent(false);
55 
56         protected virtual void Run()
57         {
58             while (true)
59             {
60                 while (!taskQueue.IsEmpty)
61                 {
62                     TaskBase t = null;
63                     if (!taskQueue.IsEmpty && taskQueue.TryDequeue(out t))
64                     {
65                         try
66                         {
67                             t.TaskRun();//執行任務
68                             t = null;
69                         }
70                         catch (Exception ex)
71                         {
72                             Logger.Error("Thread:<" + Thread.CurrentThread.Name + "> TaskRun <" + t.Name + ">", ex);
73                         }
74                     }
75                 }
76                 are.Reset();
77                 ///隊列為空等待200毫秒繼續
78                 are.WaitOne(200);
79             }
80         }
81     }
82 }

 

日志輔助任務執行器

 1 /**
 2  * 
 3  * @author 失足程序員
 4  * @Blog http://www.cnblogs.com/ty408/
 5  * @mail [email protected]
 6  * @phone 13882122019
 7  * 
 8  */
 9 namespace Sz
10 {
11     internal abstract class TaskBase
12     {
13         
14         public string Name { get; private set; }
15 
16         public TaskBase(string name)
17         {
18             this.Name = name;
19             TempAttribute = new ObjectAttribute();
20         }
21         public ObjectAttribute TempAttribute { get; set; }
22 
23         public abstract void TaskRun();
24     }
25 }

 

  1 /**
  2  * 
  3  * @author 失足程序員
  4  * @Blog http://www.cnblogs.com/ty408/
  5  * @mail [email protected]
  6  * @phone 13882122019
  7  * 
  8  */
  9 namespace Sz
 10 {
 11     /// <summary>
 12     /// 日志輔助
 13     /// </summary>
 14     public class Logger
 15     {
 16         static ThreadModel logConsoleThread = new ThreadModel("Console Log Thread");
 17         static ThreadModel logFileThread = new ThreadModel("File Log Thread");
 18         static string loginfoPath = "log/info/";
 19         static string logErrorPath = "log/error/";
 20 
 21         static Logger()
 22         {
 23             if (!Directory.Exists(loginfoPath)) { Directory.CreateDirectory(loginfoPath); }
 24             if (!Directory.Exists(logErrorPath)) { Directory.CreateDirectory(logErrorPath); }
 25         }
 26 
 27         #region 日子寫入文件輔助任務 class LogTaskFile : TaskBase
 28         /// <summary>
 29         /// 日子寫入文件輔助任務
 30         /// </summary>
 31         class LogTaskFile : TaskBase
 32         {
 33             string msg, mathed;
 34             Exception exce;
 35             int lineID;
 36             public LogTaskFile(int lineID, string mathed, string msg, Exception exce)
 37                 : base("File Log Task")
 38             {
 39                 this.mathed = mathed;
 40                 this.lineID = lineID;
 41                 this.msg = msg;
 42                 this.exce = exce;
 43             }
 44 
 45             public LogTaskFile(string msg, Exception exce)
 46                 : base("File Log Task")
 47             {
 48                 this.msg = msg;
 49                 this.exce = exce;
 50             }
 51 
 52             public override void TaskRun()
 53             {
 54                 string loginfo = "[" + DateTime.Now.NowString() + mathed.PadRight(5) + "] " + msg;
 55                 DateTime dnow = DateTime.Now;
 56                 string logPath = string.Format("{0}info_{1}{2}{3}.log", loginfoPath, dnow.Year, dnow.Month, dnow.Day);
 57                 if (!mathed.Equals("Error"))
 58                 {
 59                     System.IO.File.AppendAllText(logPath, loginfo, UTF8Encoding.Default);
 60                     System.IO.File.AppendAllText(logPath, "\r\n", UTF8Encoding.Default);
 61                 }
 62                 if (exce != null)
 63                 {
 64                     logPath = string.Format("{0}error_{1}{2}{3}.log", logErrorPath, dnow.Year, dnow.Month, dnow.Day);
 65                     StringBuilder sb = new StringBuilder();
 66                     sb.AppendLine(loginfo);
 67                     sb.AppendLine("----------------------Exception--------------------------");
 68                     sb.AppendLine(exce.Message);
 69                     sb.AppendLine(exce.StackTrace);
 70                     sb.AppendLine("----------------------Exception--------------------------");
 71                     System.IO.File.AppendAllText(logPath, sb.ToString(), UTF8Encoding.Default);
 72                     System.IO.File.AppendAllText(logPath, "\r\n", UTF8Encoding.Default);
 73                 }
 74             }
 75         }
 76         #endregion
 77 
 78         #region 日志寫入控制台輸出 class LogTaskConsole : TaskBase
 79         /// <summary>
 80         /// 日志寫入控制台輸出
 81         /// </summary>
 82         class LogTaskConsole : TaskBase
 83         {
 84             string msg, mathed;
 85             Exception exce;
 86             int lineID;
 87             public LogTaskConsole(int lineID, string mathed, string msg, Exception exce)
 88                 : base("Console Log Task")
 89             {
 90                 this.mathed = mathed;
 91                 this.lineID = lineID;
 92                 this.msg = msg;
 93                 this.exce = exce;
 94             }
 95 
 96             public LogTaskConsole(string msg, Exception exce)
 97                 : base("Console Log Task")
 98             {
 99                 this.msg = msg;
100                 this.exce = exce;
101             }
102 
103             public override void TaskRun()
104             {
105                 string loginfo = "[" + DateTime.Now.NowString() + mathed.PadRight(5) + "] " + msg;
106                 DateTime dnow = DateTime.Now;
107                 Console.WriteLine(loginfo);
108 
109                 if (exce != null)
110                 {
111                     StringBuilder sb = new StringBuilder();
112                     sb.AppendLine(loginfo);
113                     sb.AppendLine("----------------------Exception--------------------------");
114                     sb.AppendLine(exce.Message);
115                     sb.AppendLine(exce.StackTrace);
116                     sb.AppendLine("----------------------Exception--------------------------");
117                     Console.WriteLine(sb.ToString());
118                 }
119             }
120         }
121         #endregion
122 
123         string name;
124         public Logger(string name)
125         {
126             this.name = name;
127         }
128 
129         static public void Info(string msg)
130         {
131             AddLog(0, "Info", msg, null);
132         }
133 
134         static public void Error(string msg)
135         {
136             Error(msg, null);
137         }
138 
139         static public void Error(string msg, Exception exception)
140         {
141             AddLog(0, "Error", msg, exception);
142         }
143 
144         static void AddLog(int lineID, string mathed, string msg, Exception exception)
145         {
146             LogTaskConsole logConsole = new LogTaskConsole(lineID, mathed, msg, exception);
147             logConsoleThread.AddTask(logConsole);
148             LogTaskFile logFile = new LogTaskFile(lineID, mathed, msg, exception);
149             logFileThread.AddTask(logFile);
150         }
151     }
152 }

 

 

自己動手實現日志記錄功能,,雖然不比log4net的功能強大,但是沒有那麼臃腫。能給滿足自我需求。

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved