等待大循环等长耗时(>500ms)任务,采用LongRunning创建,避免占用线程池大石头 authored at 2025-11-13 10:08:32
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}");
// 长连接下线
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);
}
}
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);
}
}
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());
}
}