NewLife/NewLife.Remoting

等待大循环等长耗时(>500ms)任务,采用LongRunning创建,避免占用线程池
大石头 authored at 2025-11-13 10:08:32
5317757
Tree
1 Parent(s) cb0736f
Summary: 4 changed files with 15 additions and 22 deletions.
Modified +6 -15
Modified +3 -3
Modified +3 -4
Modified +3 -0
Modified +6 -15
diff --git a/NewLife.Remoting.Extensions/Services/WsCommandSession.cs b/NewLife.Remoting.Extensions/Services/WsCommandSession.cs
index d6e4964..2ca6f9b 100644
--- a/NewLife.Remoting.Extensions/Services/WsCommandSession.cs
+++ b/NewLife.Remoting.Extensions/Services/WsCommandSession.cs
@@ -5,8 +5,6 @@ using NewLife.Remoting.Models;
 using NewLife.Remoting.Services;
 using NewLife.Security;
 using NewLife.Serialization;
-using NewLife.Model;
-using Host = NewLife.Model.Host;
 
 namespace NewLife.Remoting.Extensions.Services;
 
@@ -16,6 +14,8 @@ public class WsCommandSession(WebSocket socket) : CommandSession
     /// <summary>是否活动中</summary>
     public override Boolean Active => socket != null && socket.State == WebSocketState.Open;
 
+    private CancellationTokenSource? _source;
+
     /// <summary>销毁</summary>
     protected override void Dispose(Boolean disposing)
     {
@@ -23,6 +23,8 @@ public class WsCommandSession(WebSocket socket) : CommandSession
 
         try
         {
+            _source?.Cancel();
+
             if (socket != null && socket.State == WebSocketState.Open)
                 socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Dispose", default);
         }
@@ -67,17 +69,7 @@ public class WsCommandSession(WebSocket socket) : CommandSession
 
         // 链接取消令牌。当客户端断开时,触发取消,结束长连接  
         using var source = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
-        // 进程退出(如 Ctrl+C)时,主动取消,尽快打断Receive等待,避免优雅超时导致的延迟退出
-        var exitDisposed = false;
-        void exitHandler()
-        {
-            try
-            {
-                if (!exitDisposed && !source.IsCancellationRequested) source.Cancel();
-            }
-            catch { /* 退出阶段避免抛异常 */ }
-        }
-        Host.RegisterExit(exitHandler);
+        _source = source;
         try
         {
             var buf = new Byte[64];
@@ -114,9 +106,8 @@ public class WsCommandSession(WebSocket socket) : CommandSession
         }
         finally
         {
-            // 标记已释放,避免退出事件晚到时对已释放的CTS再次操作
-            exitDisposed = true;
             source.Cancel();
+            _source = null;
             Log?.WriteLog("WebSocket断开", true, $"State={socket.State} CloseStatus={socket.CloseStatus} sid={sid} Remote={remote}");
 
             // 长连接下线  
Modified +3 -3
diff --git a/NewLife.Remoting/Clients/WsChannel.cs b/NewLife.Remoting/Clients/WsChannel.cs
index 35f956b..7530078 100644
--- a/NewLife.Remoting/Clients/WsChannel.cs
+++ b/NewLife.Remoting/Clients/WsChannel.cs
@@ -70,9 +70,9 @@ class WsChannel(ClientBase client) : DisposeBase
             _websocket = client;
 
             _source = new CancellationTokenSource();
-            // 进程退出(如 Ctrl+C)时,主动取消,尽快打断Receive等待
-            Host.RegisterExit(() => { try { _source?.Cancel(); } catch { } });
-            _ = TaskEx.Run(() => DoPull(client, _source));
+            //// 进程退出(如 Ctrl+C)时,主动取消,尽快打断Receive等待
+            //Host.RegisterExit(() => { try { _source?.Cancel(); } catch { } });
+            _ = Task.Factory.StartNew(() => DoPull(client, _source), TaskCreationOptions.LongRunning);
         }
     }
 
Modified +3 -4
diff --git a/NewLife.Remoting/Clients/WsChannelCore.cs b/NewLife.Remoting/Clients/WsChannelCore.cs
index 254edb1..32fab4f 100644
--- a/NewLife.Remoting/Clients/WsChannelCore.cs
+++ b/NewLife.Remoting/Clients/WsChannelCore.cs
@@ -70,10 +70,9 @@ class WsChannelCore(ClientBase client) : WsChannel(client)
             _websocket = client;
 
             _source = new CancellationTokenSource();
-            // 进程退出(如 Ctrl+C)时,主动取消,尽快打断Receive等待
-            var src = _source;
-            Host.RegisterExit(() => { try { src?.Cancel(); } catch { } });
-            _ = Task.Run(() => DoPull(client, _source));
+            //// 进程退出(如 Ctrl+C)时,主动取消,尽快打断Receive等待
+            //Host.RegisterExit(() => { try { _source?.Cancel(); } catch { } });
+            _ = Task.Factory.StartNew(() => DoPull(client, _source), TaskCreationOptions.LongRunning);
         }
     }
 
Modified +3 -0
diff --git a/NewLife.Remoting/Services/SessionManager.cs b/NewLife.Remoting/Services/SessionManager.cs
index 07b87cf..798185d 100644
--- a/NewLife.Remoting/Services/SessionManager.cs
+++ b/NewLife.Remoting/Services/SessionManager.cs
@@ -62,6 +62,9 @@ public class SessionManager(IServiceProvider serviceProvider) : DisposeBase, ISe
             if (Bus != null) return;
 
             Bus = Create();
+
+            // 进程退出(如 Ctrl+C)时,主动销毁会话管理器,尽快打断会话的Receive等待
+            Host.RegisterExit(() => this.TryDispose());
         }
     }