Explorar o código

修复linux上UServiceTest单元测试crash,bug原因是因为UService Dispose的时候没有将拥有的UChannel Dispose

tanghai %!s(int64=11) %!d(string=hai) anos
pai
achega
95b602ebde

+ 1 - 1
CSharp/Game/Model/Component/NetworkComponent.cs

@@ -27,7 +27,7 @@ namespace Model
 
 			this.service.Add(this.AcceptChannel);
 
-			this.service.Run();
+			this.service.Start();
 		}
 
 		/// <summary>

+ 3 - 1
CSharp/Platform/Common/Network/IService.cs

@@ -28,6 +28,8 @@ namespace Common.Network
 
 		void RunOnce(int timeout);
 
-		void Run();
+		void Start();
+
+		void Stop();
 	}
 }

+ 16 - 2
CSharp/Platform/TNet/TService.cs

@@ -1,5 +1,6 @@
 using System;
 using System.Collections.Generic;
+using System.Linq;
 using System.Threading.Tasks;
 using Common.Base;
 using Common.Network;
@@ -18,6 +19,8 @@ namespace TNet
 
 		private readonly TimerManager timerManager = new TimerManager();
 
+		private bool isStop;
+
 		/// <summary>
 		/// 即可做client也可做server
 		/// </summary>
@@ -46,9 +49,15 @@ namespace TNet
 
 			if (disposing)
 			{
+				foreach (ObjectId id in idChannels.Keys.ToArray())
+				{
+					TChannel channel = idChannels[id];
+					channel.Dispose();
+				}
 				this.acceptor.Dispose();
 			}
 
+			isStop = true;
 			this.acceptor = null;
 		}
 
@@ -126,15 +135,20 @@ namespace TNet
 			this.poller.Run(timeout);
 		}
 
-		public void Run()
+		public void Start()
 		{
-			while (true)
+			while (!isStop)
 			{
 				this.RunOnce(1);
 				this.timerManager.Refresh();
 			}
 		}
 
+		public void Stop()
+		{
+			this.isStop = true;
+		}
+
 		internal TimerManager Timer
 		{
 			get

+ 2 - 2
CSharp/Platform/TNetTest/TServiceTest.cs

@@ -43,8 +43,8 @@ namespace TNetTest
 			IService clientService = new TService();
 			IService serverService = new TService(hostName, 8889);
 
-			Task.Factory.StartNew(() => clientService.Run(), TaskCreationOptions.LongRunning);
-			Task.Factory.StartNew(() => serverService.Run(), TaskCreationOptions.LongRunning);
+			Task.Factory.StartNew(() => clientService.Start(), TaskCreationOptions.LongRunning);
+			Task.Factory.StartNew(() => serverService.Start(), TaskCreationOptions.LongRunning);
 
 			// 往server host线程增加事件,accept
 			serverService.Add(() => this.ServerEvent(serverService));

+ 0 - 8
CSharp/Platform/UNet/UPoller.cs

@@ -278,13 +278,5 @@ namespace UNet
 				}
 			}
 		}
-
-		public void Run(int timeout = 0)
-		{
-			while (true)
-			{
-				this.RunOnce(timeout);
-			}
-		}
 	}
 }

+ 19 - 2
CSharp/Platform/UNet/UService.cs

@@ -1,5 +1,6 @@
 using System;
 using System.Collections.Generic;
+using System.Linq;
 using System.Threading.Tasks;
 using Common.Network;
 using MongoDB.Bson;
@@ -14,6 +15,8 @@ namespace UNet
 
 		private readonly Dictionary<ObjectId, UChannel> idChannels = new Dictionary<ObjectId, UChannel>();
 
+		private bool isStop;
+
 		/// <summary>
 		/// 即可做client也可做server
 		/// </summary>
@@ -41,8 +44,14 @@ namespace UNet
 
 			if (disposing)
 			{
+				foreach (ObjectId id in idChannels.Keys.ToArray())
+				{
+					UChannel channel = idChannels[id];
+					channel.Dispose();
+				}
 				this.poller.Dispose();
 			}
+
 			this.poller = null;
 		}
 
@@ -113,9 +122,17 @@ namespace UNet
 			this.poller.RunOnce(timeout);
 		}
 
-		public void Run()
+		public void Start()
+		{
+			while (!isStop)
+			{
+				this.poller.RunOnce();
+			}
+		}
+
+		public void Stop()
 		{
-			this.poller.Run();
+			this.isStop = true;
 		}
 	}
 }

+ 19 - 15
CSharp/Platform/UNetTest/UServiceTest.cs

@@ -12,16 +12,16 @@ namespace UNetTest
 	[TestFixture]
 	public class UServiceTest
 	{
-		private readonly Barrier barrier = new Barrier(3);
+		private readonly Barrier barrier = new Barrier(2);
 
-		private async void ClientEvent(IService service, string hostName, ushort port)
+		private async void ClientEvent(IService clientService, string hostName, ushort port)
 		{
-			AChannel channel = await service.GetChannel(hostName, port);
+			AChannel channel = await clientService.GetChannel(hostName, port);
 			channel.SendAsync("0123456789".ToByteArray());
 
 			byte[] bytes = await channel.RecvAsync();
 			CollectionAssert.AreEqual("9876543210".ToByteArray(), bytes);
-			this.barrier.RemoveParticipant();
+			barrier.RemoveParticipant();
 		}
 
 		private async void ServerEvent(IService service)
@@ -31,7 +31,6 @@ namespace UNetTest
 			CollectionAssert.AreEqual("0123456789".ToByteArray(), bytes);
 			Array.Reverse(bytes);
 			channel.SendAsync(bytes);
-			this.barrier.RemoveParticipant();
 		}
 
 		[Test]
@@ -39,20 +38,25 @@ namespace UNetTest
 		{
 			const string hostName = "127.0.0.1";
 			const ushort port = 8889;
-			IService clientService = new UService(hostName, 8888);
-			IService serverService = new UService(hostName, 8889);
+			using (IService clientService = new UService(hostName, 8888))
+			using (IService serverService = new UService(hostName, 8889))
+			{	
+				Task task1 = Task.Factory.StartNew(() => clientService.Start(), TaskCreationOptions.LongRunning);
+				Task task2 = Task.Factory.StartNew(() => serverService.Start(), TaskCreationOptions.LongRunning);
 
-			Task.Factory.StartNew(() => clientService.Run(), TaskCreationOptions.LongRunning);
-			Task.Factory.StartNew(() => serverService.Run(), TaskCreationOptions.LongRunning);
+				// 往server host线程增加事件,accept
+				serverService.Add(() => this.ServerEvent(serverService));
 
-			// 往server host线程增加事件,accept
-			serverService.Add(() => this.ServerEvent(serverService));
+				Thread.Sleep(1000);
 
-			Thread.Sleep(1000);
+				// 往client host线程增加事件,client线程连接server
+				clientService.Add(() => this.ClientEvent(clientService, hostName, port));
+				barrier.SignalAndWait();
 
-			// 往client host线程增加事件,client线程连接server
-			clientService.Add(() => this.ClientEvent(clientService, hostName, port));
-			this.barrier.SignalAndWait();
+				serverService.Add(serverService.Stop);
+				clientService.Add(clientService.Stop);
+				Task.WaitAll(task1, task2);
+			}
 		}
 	}
 }