解决MySql布尔型新旧版本兼容问题,采用枚举来表示布尔型的数据表。由正向工程赋值
大石头 authored at 2018-05-15 21:21:05
8.44 KiB
X
# ¿ÉÏú»Ù DisposeBase ## ¸ÅÊö `DisposeBase` ÊÇ NewLife.Core ÖÐʵÏÖ `IDisposable` ģʽµÄ³éÏó»ùÀ࣬Ìṩ±ê×¼µÄ×ÊÔ´ÊÍ·Åģʽ£¬ÓÐЧ·ÀÖ¹ÄÚ´æºÍ×ÊԴй©¡£ËüÈ·±£ÊÍ·ÅÂß¼­Ö»Ö´ÐÐÒ»´Î£¬²¢Ö§³ÖÏú»Ùʼþ֪ͨ¡£ **ÃüÃû¿Õ¼ä**£º`NewLife` **ÎĵµµØÖ·**£ºhttps://newlifex.com/core/disposebase ## ºËÐÄÌØÐÔ - **±ê×¼ Dispose ģʽ**£ºÕýȷʵÏÖ `IDisposable` ½Ó¿Ú - **µ¥´ÎÊͷű£Ö¤**£ºÍ¨¹ýÔ­×Ó²Ù×÷È·±£ÊÍ·ÅÂß¼­Ö»Ö´ÐÐÒ»´Î - **ÖÕ½áÆ÷Ö§³Ö**£ºÔÚÍü¼Çµ÷Óà `Dispose` ʱÌṩ¶µµ×ÊÍ·Å - **Ïú»Ùʼþ**£ºÖ§³ÖÔÚ¶ÔÏóÏú»Ùʱ´¥·¢Ê¼þ֪ͨ - **¸¨Öú·½·¨**£ºÌṩ `ThrowIfDisposed` ºÍ `TryDispose` µÈ¸¨Öú·½·¨ ## ¿ìËÙ¿ªÊ¼ ```csharp using NewLife; // ¼Ì³Ð DisposeBase ʵÏÖ×ÊÔ´¹ÜÀí public class MyResource : DisposeBase { private Stream _stream; public MyResource(String path) { _stream = File.OpenRead(path); } protected override void Dispose(Boolean disposing) { base.Dispose(disposing); if (disposing) { // ÊÍ·ÅÍйÜ×ÊÔ´ _stream?.Dispose(); _stream = null; } } } // ʹÓà using Óï¾ä×Ô¶¯ÊÍ·Å using var resource = new MyResource("data.txt"); ``` ## API ²Î¿¼ ### IDisposable2 ½Ó¿Ú ```csharp public interface IDisposable2 : IDisposable { Boolean Disposed { get; } event EventHandler OnDisposed; } ``` À©Õ¹µÄ¿ÉÏú»Ù½Ó¿Ú£¬Ôö¼ÓÁË `Disposed` ״̬ÊôÐÔºÍÏú»Ùʼþ¡£ ### DisposeBase Àà #### ÊôÐÔ ##### Disposed ```csharp public Boolean Disposed { get; } ``` ±íʾ¶ÔÏóÊÇ·ñÒѱ»ÊÍ·Å¡£ **ʾÀý**£º ```csharp var resource = new MyResource(); Console.WriteLine(resource.Disposed); // False resource.Dispose(); Console.WriteLine(resource.Disposed); // True ``` #### ·½·¨ ##### Dispose ```csharp public void Dispose() ``` ÊÍ·Å×ÊÔ´¡£µ÷Óúó»á´¥·¢ `OnDisposed` ʼþ£¬²¢Í¨Öª GC ²»ÔÙµ÷ÓÃÖÕ½áÆ÷¡£ ##### Dispose(Boolean) ```csharp protected virtual void Dispose(Boolean disposing) ``` ʵ¼ÊµÄ×ÊÔ´ÊÍ·Å·½·¨£¬×ÓÀàÖØÔØ´Ë·½·¨ÊµÏÖ¾ßÌåµÄÊÍ·ÅÂß¼­¡£ **²ÎÊý˵Ã÷**£º - `disposing`£º`true` ±íʾ´Ó `Dispose()` ·½·¨µ÷Óã¬Ó¦ÊÍ·ÅËùÓÐ×ÊÔ´£»`false` ±íʾ´ÓÖÕ½áÆ÷µ÷Óã¬Ö»Ó¦ÊÍ·Å·ÇÍйÜ×ÊÔ´ **ÖØÔØÊ¾Àý**£º ```csharp protected override void Dispose(Boolean disposing) { // 1. Ê×Ïȵ÷ÓûùÀà·½·¨ base.Dispose(disposing); // 2. ÊÍ·ÅÍйÜ×ÊÔ´£¨½öµ±´Ó Dispose() µ÷ÓÃʱ£© if (disposing) { _managedResource?.Dispose(); _managedResource = null; } // 3. ÊÍ·Å·ÇÍйÜ×ÊÔ´£¨Á½ÖÖ·¾¶¶¼Ö´ÐУ© if (_handle != IntPtr.Zero) { CloseHandle(_handle); _handle = IntPtr.Zero; } } ``` ##### ThrowIfDisposed ```csharp protected void ThrowIfDisposed() ``` ÔÚ¹«¿ª·½·¨Öе÷Óã¬Èô¶ÔÏóÒÑÊÍ·ÅÔòÅ׳ö `ObjectDisposedException`¡£ **ʾÀý**£º ```csharp public class MyResource : DisposeBase { public void DoWork() { ThrowIfDisposed(); // ÒÑÊÍ·ÅʱÅ׳öÒì³£ // Ö´ÐÐʵ¼Ê¹¤×÷... } } ``` #### ʼþ ##### OnDisposed ```csharp public event EventHandler? OnDisposed ``` ¶ÔÏó±»Ïú»Ùʱ´¥·¢µÄʼþ¡£ **×¢Òâ**£ºÊ¼þ¿ÉÄÜÔÚÖÕ½áÆ÷Ïß³ÌÖд¥·¢£¬¶©ÔÄ·½Ó¦±ÜÃâÒÀÀµÌض¨Ïß³ÌÉÏÏÂÎÄ¡£ **ʾÀý**£º ```csharp var resource = new MyResource(); resource.OnDisposed += (sender, e) => { Console.WriteLine("×ÊÔ´ÒÑÊÍ·Å"); }; resource.Dispose(); // Êä³ö£º×ÊÔ´ÒÑÊÍ·Å ``` ### DisposeHelper ¸¨ÖúÀà #### TryDispose ```csharp public static Object? TryDispose(this Object? obj) ``` ³¢ÊÔÏú»Ù¶ÔÏó£¬Èç¹û¶ÔÏóʵÏÖÁË `IDisposable` Ôòµ÷ÓÃÆä `Dispose` ·½·¨¡£Ö§³Ö¼¯ºÏÀàÐÍ£¬»á±éÀúÏú»ÙËùÓÐÔªËØ¡£ **ʾÀý**£º ```csharp // Ïú»Ùµ¥¸ö¶ÔÏó var stream = File.OpenRead("test.txt"); stream.TryDispose(); // Ïú»Ù¼¯ºÏÖеÄËùÓжÔÏó var streams = new List<Stream> { File.OpenRead("a.txt"), File.OpenRead("b.txt"), File.OpenRead("c.txt") }; streams.TryDispose(); // Ïú»ÙËùÓÐÁ÷ ``` ## ʹÓó¡¾° ### 1. ¹ÜÀíÎļþ¾ä±ú ```csharp public class FileProcessor : DisposeBase { private FileStream? _fileStream; private StreamReader? _reader; public FileProcessor(String path) { _fileStream = File.OpenRead(path); _reader = new StreamReader(_fileStream); } public String ReadLine() { ThrowIfDisposed(); return _reader?.ReadLine() ?? String.Empty; } protected override void Dispose(Boolean disposing) { base.Dispose(disposing); if (disposing) { _reader?.Dispose(); _reader = null; _fileStream?.Dispose(); _fileStream = null; } } } ``` ### 2. ¹ÜÀíÍøÂçÁ¬½Ó ```csharp public class TcpConnection : DisposeBase { private Socket? _socket; private NetworkStream? _stream; public TcpConnection(String host, Int32 port) { _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); _socket.Connect(host, port); _stream = new NetworkStream(_socket, ownsSocket: false); } public void Send(Byte[] data) { ThrowIfDisposed(); _stream?.Write(data, 0, data.Length); } protected override void Dispose(Boolean disposing) { base.Dispose(disposing); if (disposing) { _stream?.Dispose(); _stream = null; _socket?.Dispose(); _socket = null; } } } ``` ### 3. ×ÊÔ´³Ø¹ÜÀí ```csharp public class ResourcePool<T> : DisposeBase where T : IDisposable { private readonly ConcurrentBag<T> _pool = new(); private readonly Func<T> _factory; public ResourcePool(Func<T> factory) { _factory = factory; } public T Rent() { ThrowIfDisposed(); return _pool.TryTake(out var item) ? item : _factory(); } public void Return(T item) { if (Disposed) { item.Dispose(); return; } _pool.Add(item); } protected override void Dispose(Boolean disposing) { base.Dispose(disposing); if (disposing) { while (_pool.TryTake(out var item)) { item.Dispose(); } } } } ``` ### 4. ¼àÌýÏú»Ùʼþ ```csharp public class ResourceMonitor { public void Monitor(IDisposable2 resource) { resource.OnDisposed += (sender, e) => { var name = sender?.GetType().Name; Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] {name} ÒÑÊÍ·Å"); }; } } // ʹÓà var monitor = new ResourceMonitor(); var resource = new MyResource(); monitor.Monitor(resource); resource.Dispose(); // Êä³ö£º[12:30:45] MyResource ÒÑÊÍ·Å ``` ## ×î¼Ñʵ¼ù ### 1. ×ÜÊǵ÷ÓûùÀà·½·¨ ```csharp protected override void Dispose(Boolean disposing) { // ? Ê×Ïȵ÷ÓûùÀà·½·¨ base.Dispose(disposing); // È»ºóÊÍ·Å×Ô¼ºµÄ×ÊÔ´ if (disposing) { /* ... */ } } ``` ### 2. ʹÓà using Óï¾ä ```csharp // ? ÍÆ¼ö£ºÊ¹Óà using Óï¾äÈ·±£ÊÍ·Å using var resource = new MyResource(); // ? ²»ÍƼö£ºÊÖ¶¯µ÷Óà Dispose£¬ÈÝÒ×ÒÅÍü var resource = new MyResource(); try { // ʹÓÃ×ÊÔ´ } finally { resource.Dispose(); } ``` ### 3. ÔÚ¹«¿ª·½·¨Öмì²é״̬ ```csharp public class MyResource : DisposeBase { public void DoWork() { // ? ÔÚ·½·¨¿ªÊ¼Ê±¼ì²éÊÇ·ñÒÑÊÍ·Å ThrowIfDisposed(); // Ö´ÐÐʵ¼Ê¹¤×÷ } } ``` ### 4. ÕýÈ·´¦ÀíÍйܺͷÇÍйÜ×ÊÔ´ ```csharp protected override void Dispose(Boolean disposing) { base.Dispose(disposing); // ÍйÜ×ÊÔ´£º½öÔÚ disposing=true ʱÊÍ·Å if (disposing) { _managedObject?.Dispose(); } // ·ÇÍйÜ×ÊÔ´£ºÁ½ÖÖÇé¿ö¶¼ÒªÊÍ·Å if (_nativeHandle != IntPtr.Zero) { NativeMethods.CloseHandle(_nativeHandle); _nativeHandle = IntPtr.Zero; } } ``` ### 5. ±ÜÃâÔÚÖÕ½áÆ÷ÖÐÅ׳öÒì³£ ```csharp // DisposeBase ÒѾ­´¦ÀíÁËÖÕ½áÆ÷ÖеÄÒì³£ // ×ÓÀàµÄ Dispose(Boolean) ·½·¨Ò²Ó¦¸Ã²¶»ñ¿ÉÄܵÄÒì³£ protected override void Dispose(Boolean disposing) { base.Dispose(disposing); try { // ÊÍ·Å×ÊÔ´ } catch (Exception ex) { // ¼Ç¼µ«²»Å׳ö XTrace.WriteException(ex); } } ``` ## Dispose ģʽÏê½â ``` µ÷Óà Dispose() ©¦ ¨‹ Dispose(true) ©¦ ©À©¤©¤? ÊÍ·ÅÍйÜ×ÊÔ´ ©¦ ©À©¤©¤? ÊÍ·Å·ÇÍйÜ×ÊÔ´ ©¦ ©À©¤©¤? ´¥·¢ OnDisposed ʼþ ©¦ ©¸©¤©¤? GC.SuppressFinalize(this) ©¦ ©¸©¤©¤? ÖÕ½áÆ÷²»ÔÙ±»µ÷Óà ÖÕ½áÆ÷ ~DisposeBase() (Èç¹ûÍü¼Çµ÷Óà Dispose) ©¦ ¨‹ Dispose(false) ©¦ ©À©¤©¤? ÊÍ·Å·ÇÍйÜ×ÊÔ´ ©¦ ©¸©¤©¤? ´¥·¢ OnDisposed ʼþ ``` ## Ïà¹ØÁ´½Ó - [¶ÔÏó³Ø ObjectPool](/NewLife/X/Blob/master/Doc/object_pool-¶ÔÏó³ØObjectPool.md) - [¶ÔÏóÈÝÆ÷ ObjectContainer](/NewLife/X/Blob/master/Doc/object_container-¶ÔÏóÈÝÆ÷ObjectContainer.md)