You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

295 lines
8.8 KiB

  1. using Apewer.Internals;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Reflection;
  5. using System.Runtime.CompilerServices;
  6. using System.Threading;
  7. using System.IO;
  8. using System.Diagnostics;
  9. #if NET461
  10. using System.Runtime.Caching;
  11. #endif
  12. #if NETFX || NETCORE
  13. using System.Windows.Forms;
  14. #endif
  15. namespace Apewer
  16. {
  17. /// <summary>核心方法。</summary>
  18. public class KernelUtility
  19. {
  20. /// <summary>强制对所有代进行即时垃圾回收。</summary>
  21. public static void Collect()
  22. {
  23. GC.Collect();
  24. }
  25. /// <summary>当前进程为 64 位。</summary>
  26. public static bool IsInX64
  27. {
  28. #if NET20
  29. get { return IntPtr.Size == 8; }
  30. #else
  31. get { return Environment.Is64BitProcess && IntPtr.Size == 8; }
  32. #endif
  33. }
  34. #region Collect | Dispose
  35. /// <summary>开始自动释放内存,默认间隔为 1000 毫秒。</summary>
  36. public static void StartAutoFree()
  37. {
  38. KernelHelper.StartFree(1000);
  39. }
  40. /// <summary>开始自动释放内存,间隔以毫秒为单位。</summary>
  41. public static void StartAutoFree(int milliseconds)
  42. {
  43. KernelHelper.StartFree(milliseconds);
  44. }
  45. /// <summary>停止自动释放内存。</summary>
  46. public static void StopAutoFree()
  47. {
  48. KernelHelper.StopFree();
  49. }
  50. /// <summary>释放。</summary>
  51. public static void Dispose(object target, bool flush = false)
  52. {
  53. if (target == null) return;
  54. var stream = target as Stream;
  55. if (stream != null)
  56. {
  57. if (flush)
  58. {
  59. try { stream.Flush(); } catch { }
  60. }
  61. try { stream.Close(); } catch { }
  62. }
  63. var disposable = target as IDisposable;
  64. if (disposable != null)
  65. {
  66. try
  67. {
  68. disposable.Dispose();
  69. }
  70. catch { }
  71. }
  72. }
  73. /// <summary>释放。</summary>
  74. public static void Dispose<T>(IEnumerable<T> objects, bool flush = false)
  75. {
  76. if (objects != null)
  77. {
  78. foreach (var i in objects) Dispose(i, flush);
  79. }
  80. }
  81. #endregion
  82. #region Thread
  83. /// <summary>停止线程。</summary>
  84. public static void Abort(Thread thread)
  85. {
  86. if (thread == null) return;
  87. try
  88. {
  89. if (thread.IsAlive) thread.Abort();
  90. }
  91. catch { }
  92. }
  93. /// <summary>阻塞当前线程,时长以毫秒为单位。</summary>
  94. public static void Sleep(int milliseconds)
  95. {
  96. if (milliseconds > 0) Thread.Sleep(milliseconds);
  97. }
  98. /// <summary></summary>
  99. [MethodImpl(MethodImplOptions.NoInlining)]
  100. public static Thread InBackground(Action action)
  101. {
  102. if (action == null) return null;
  103. var thread = new Thread(delegate (object v) { ((Action)v)(); });
  104. thread.IsBackground = true;
  105. thread.Start(action);
  106. return thread;
  107. }
  108. /// <summary>启动线程。</summary>
  109. public static Thread StartThread(Action action, bool background = true)
  110. {
  111. if (action == null) return null;
  112. var thread = new Thread(new ThreadStart(action));
  113. thread.IsBackground = background;
  114. thread.Start();
  115. return thread;
  116. }
  117. #endregion
  118. #region Assembly
  119. /// <summary>获取当前进程程序集的资源。</summary>
  120. public static byte[] GetAssemblyResource(string name)
  121. {
  122. var assembly = Assembly.GetExecutingAssembly();
  123. return GetAssemblyResource(assembly, name);
  124. }
  125. /// <summary>获取指定程序集的资源。</summary>
  126. public static byte[] GetAssemblyResource(Assembly assembly, string name)
  127. {
  128. var result = Constant.EmptyBytes;
  129. if (assembly == null) return null;
  130. try
  131. {
  132. var source = assembly.GetManifestResourceStream(name);
  133. result = StreamHelper.Read(source);
  134. Dispose(source);
  135. }
  136. finally { }
  137. return result;
  138. }
  139. /// <summary>获取已加载的程序集。</summary>
  140. public static Assembly[] GetLoadedAssemblies()
  141. {
  142. return AppDomain.CurrentDomain.GetAssemblies();
  143. }
  144. #endregion
  145. #region Cache
  146. #if NET461
  147. /// <summary>设置缓存项。</summary>
  148. public static bool CacheSet(string key, object value, int minutes = 60)
  149. {
  150. if (TextUtility.IsEmpty(key)) return false;
  151. if (minutes < 1) return false;
  152. var policy = new CacheItemPolicy();
  153. policy.AbsoluteExpiration = DateTimeOffset.Now.AddMinutes((double)NumberUtility.RestrictValue(minutes, 0, 525600));
  154. var instance = MemoryCache.Default;
  155. instance.Set(key, value, policy, null);
  156. return true;
  157. }
  158. /// <summary></summary>
  159. public static object CacheGet(string key)
  160. {
  161. if (TextUtility.IsEmpty(key)) return null;
  162. var instance = MemoryCache.Default;
  163. var entity = instance.Get(key, null);
  164. return entity;
  165. }
  166. /// <summary></summary>
  167. public static object CacheRemove(string key)
  168. {
  169. if (TextUtility.IsEmpty(key)) return null;
  170. var instance = MemoryCache.Default;
  171. var entity = instance.Remove(key, null);
  172. return entity;
  173. }
  174. #endif
  175. #endregion
  176. #region Application
  177. #if NETFX || NETCORE
  178. /// <summary>
  179. /// <para>System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase</para>
  180. /// <para>D:\Website\</para>
  181. /// </summary>
  182. public static string ApplicationBasePath {get=> AppDomain.CurrentDomain.SetupInformation.ApplicationBase; }
  183. /// <summary>处理当前在消息队列中的所有 Windows 消息。</summary>
  184. public static void DoEvents() => Application.DoEvents();
  185. /// <summary>
  186. /// <para>System.Windows.Forms.Application.StartupPath</para>
  187. /// <para>c:\windows\system32\inetsrv</para>
  188. /// </summary>
  189. public static string StartupPath { get => Application.StartupPath; }
  190. /// <summary>
  191. /// <para>System.Windows.Forms.Application.ExecutablePath</para>
  192. /// <para>c:\windows\system32\inetsrv\w3wp.exe</para>
  193. /// </summary>
  194. public static string ExecutablePath { get => Application.ExecutablePath; }
  195. #region System.Windows.Forms.Application
  196. /// <summary>在没有窗体的情况下,在当前线程上开始运行标准应用程序消息循环。</summary>
  197. /// <exception cref="InvalidOperationException"></exception>
  198. public static void ApplicationRun() => Application.Run();
  199. /// <summary>在当前线程上开始运行标准应用程序消息循环,并使指定窗体可见。</summary>
  200. /// <exception cref="InvalidOperationException"></exception>
  201. public static void ApplicationRun(Form form) => Application.Run(form);
  202. /// <summary>关闭应用程序并立即启动一个新实例。</summary>
  203. public static void ApplicationRestart() => Application.Restart();
  204. /// <summary>通知所有消息泵必须终止,并且在处理了消息以后关闭所有应用程序窗口。</summary>
  205. public static void ApplicationExit() => Application.Exit();
  206. /// <summary>退出当前线程上的消息循环,并关闭该线程上的所有窗口。</summary>
  207. public static void ApplicationExitThread() => Application.ExitThread();
  208. #endregion
  209. #endif
  210. /// <summary>
  211. /// <para>System.AppDomain.CurrentDomain.BaseDirectory</para>
  212. /// <para>D:\Website\</para>
  213. /// </summary>
  214. private static string CurrentDomainPath
  215. {
  216. get { return AppDomain.CurrentDomain.BaseDirectory; }
  217. }
  218. /// <summary>
  219. /// <para>System.IO.Directory.GetCurrentDirectory()</para>
  220. /// <para>c:\windows\system32\inetsrv</para>
  221. /// </summary>
  222. private static string CurrentDirectory
  223. {
  224. get { return Directory.GetCurrentDirectory(); } // System.Environment.CurrentDirectory
  225. }
  226. /// <summary>
  227. /// <para>System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName</para>
  228. /// <para>c:\windows\system32\inetsrv\w3wp.exe</para>
  229. /// </summary>
  230. private static string ProcessMainModule
  231. {
  232. get { return Process.GetCurrentProcess().MainModule.FileName; }
  233. }
  234. #endregion
  235. }
  236. }