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 492794628@qq.com
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 492794628@qq.com
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 492794628@qq.com
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的功能強大,但是沒有那麼臃腫。能給滿足自我需求。