Sfoglia il codice sorgente

正确实现IDisposable接口,请看TChannel的实现

tanghai 11 anni fa
parent
commit
7bddc88829

+ 20 - 2
CSharp/Platform/TNet/TChannel.cs

@@ -28,17 +28,35 @@ namespace TNet
 			this.parser = new PacketParser(recvBuffer);
 		}
 
-		public void Dispose()
+		protected virtual void Dispose(bool disposing)
 		{
 			if (socket == null)
 			{
 				return;
 			}
+
+			if (disposing)
+			{
+				// 释放托管的资源
+				socket.Dispose();
+			}
+
+			// 释放非托管资源
 			this.service.Remove(this);
-			socket.Dispose();
 			this.socket = null;
 		}
 
+		~TChannel()
+		{
+			this.Dispose(false);
+		}
+
+		public void Dispose()
+		{
+			Dispose(true);
+			GC.SuppressFinalize(this);
+		}
+
 		public void SendAsync(byte[] buffer, byte channelID = 0, PacketFlags flags = PacketFlags.Reliable)
 		{
 			byte[] size = BitConverter.GetBytes(buffer.Length);

+ 20 - 5
CSharp/Platform/TNet/TService.cs

@@ -16,7 +16,7 @@ namespace TNet
 		private readonly TimerManager timerManager = new TimerManager();
 
 		/// <summary>
-		/// 用作server端的构造函数
+		/// 即可做client也可做server
 		/// </summary>
 		/// <param name="host"></param>
 		/// <param name="port"></param>
@@ -28,23 +28,38 @@ namespace TNet
 		}
 
 		/// <summary>
-		/// 用作client端的构造函数
+		/// 只能做client端的构造函数
 		/// </summary>
 		public TService()
 		{
 		}
 
-		public void Dispose()
+		protected virtual void Dispose(bool disposing)
 		{
 			if (this.acceptor == null)
 			{
 				return;
 			}
-			
-			this.acceptor.Dispose();
+
+			if (disposing)
+			{
+				this.acceptor.Dispose();
+			}
+
 			this.acceptor = null;
 		}
 
+		~TService()
+		{
+			this.Dispose(false);
+		}
+
+		public void Dispose()
+		{
+			Dispose(true);
+			GC.SuppressFinalize(this);
+		}
+
 		public void Add(Action action)
 		{
 			this.poller.Add(action);

+ 22 - 6
CSharp/Platform/TNet/TSocket.cs

@@ -8,8 +8,8 @@ namespace TNet
 {
 	public class TSocket
 	{
-		private IPoller poller;
-		private readonly Socket socket;
+		private readonly IPoller poller;
+		private Socket socket;
 		private readonly SocketAsyncEventArgs innArgs = new SocketAsyncEventArgs();
 		private readonly SocketAsyncEventArgs outArgs = new SocketAsyncEventArgs();
 
@@ -45,14 +45,30 @@ namespace TNet
 			}
 		}
 
-		public void Dispose()
+		protected virtual void Dispose(bool disposing)
 		{
-			if (this.poller == null)
+			if (this.socket == null)
 			{
 				return;
 			}
-			this.socket.Dispose();
-			this.poller = null;
+
+			if (disposing)
+			{
+				this.socket.Dispose();
+			}
+
+			this.socket = null;
+		}
+
+		~TSocket()
+		{
+			this.Dispose(false);
+		}
+
+		public void Dispose()
+		{
+			Dispose(true);
+			GC.SuppressFinalize(this);
 		}
 
 		public void Bind(string host, int port)

+ 20 - 3
CSharp/Platform/UNet/UChannel.cs

@@ -1,4 +1,5 @@
-using System.Threading.Tasks;
+using System;
+using System.Threading.Tasks;
 using Network;
 
 namespace UNet
@@ -15,17 +16,33 @@ namespace UNet
 			this.service = service;
 		}
 
-		public void Dispose()
+		protected void Dispose(bool disposing)
 		{
 			if (socket == null)
 			{
 				return;
 			}
+			
+			if (disposing)
+			{
+				socket.Dispose();
+			}
+
 			service.Remove(this);
-			socket.Dispose();
 			this.socket = null;
 		}
 
+		~UChannel()
+		{
+			Dispose(false);
+		}
+
+		public void Dispose()
+		{
+			Dispose(true);
+			GC.SuppressFinalize(this);
+		}
+
 		public void SendAsync(byte[] buffer, byte channelID = 0, PacketFlags flags = PacketFlags.Reliable)
 		{
 			this.socket.WriteAsync(buffer, channelID, flags);

+ 26 - 3
CSharp/Platform/UNet/UService.cs

@@ -5,32 +5,55 @@ using Network;
 
 namespace UNet
 {
-	public class UService: IService
+	public sealed class UService: IService
 	{
 		private EService service;
 
 		private readonly Dictionary<string, UChannel> channels = new Dictionary<string, UChannel>();
 
+		/// <summary>
+		/// 即可做client也可做server
+		/// </summary>
+		/// <param name="host"></param>
+		/// <param name="port"></param>
 		public UService(string host, int port)
 		{
 			this.service = new EService(host, (ushort)port);
 		}
 
+		/// <summary>
+		/// 只能做client
+		/// </summary>
 		public UService()
 		{
 			this.service = new EService();
 		}
 
-		public void Dispose()
+		private void Dispose(bool disposing)
 		{
 			if (service == null)
 			{
 				return;
 			}
-			service.Dispose();
+
+			if (disposing)
+			{
+				service.Dispose();	
+			}
 			service = null;
 		}
 
+		~UService()
+		{
+			Dispose(false);
+		}
+
+		public void Dispose()
+		{
+			Dispose(true);
+			GC.SuppressFinalize(this);
+		}
+
 		public void Add(Action action)
 		{
 			this.service.Events += action;

+ 13 - 1
CSharp/Platform/UNet/USocket.cs

@@ -22,16 +22,28 @@ namespace UNet
 			this.service = service;
 		}
 
-		public void Dispose()
+		private void Dispose(bool disposing)
 		{
 			if (this.peerPtr == IntPtr.Zero)
 			{
 				return;
 			}
+
 			NativeMethods.EnetPeerReset(this.peerPtr);
 			this.peerPtr = IntPtr.Zero;
 		}
 
+		~USocket()
+		{
+			Dispose(false);
+		}
+
+		public void Dispose()
+		{
+			Dispose(true);
+			GC.SuppressFinalize(this);
+		}
+
 		public IntPtr PeerPtr
 		{
 			get

+ 1 - 3
CSharp/Platform/UNetTest/UServiceTest.cs

@@ -2,11 +2,9 @@
 using System.Threading;
 using System.Threading.Tasks;
 using Common.Helper;
-using Common.Logger;
 using UNet;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using Network;
-using TNet;
 
 namespace UNetTest
 {
@@ -42,7 +40,7 @@ namespace UNetTest
 		{
 			const string hostName = "127.0.0.1";
 			const ushort port = 8889;
-			IService clientService = new UService();
+			IService clientService = new UService(hostName, 8888);
 			IService serverService = new UService(hostName, 8889);
 
 			Task.Factory.StartNew(() => clientService.Run(), TaskCreationOptions.LongRunning);