• 辅助功能性代码,研究和记录代码。


    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, "
    ", 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, "
    ", 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的功能强大,但是没有那么臃肿。能给满足自我需求。

  • 相关阅读:
    新人补钙系列教程之:回调函数
    新人补钙系列教程之:卡马克卷轴算法
    新人补钙系列教程之:体验ApplicationDomain 应用程序域
    新人补钙系列教程之:一天一招让你的代码越来越好
    新人补钙系列教程之:AS3 与 PHP 简单通信基础
    新人补钙系列教程之:Molehill底层API中最重要的Context3D
    新人补钙系列教程之:AS 与 JS 相互通信
    新人补钙系列教程之:AS3 位运算符
    新人补钙系列教程之:XML处理方法
    新人补钙系列教程之:网页游戏分线到不分线
  • 原文地址:https://www.cnblogs.com/shizuchengxuyuan/p/4450654.html
Copyright © 2020-2023  润新知