TaskCreationOptions.LongRunning 运行比可用线程数更多的任务

本文探讨了在使用WebSocket服务时遇到的问题,即如何处理超过可用线程数的任务监听。通过介绍TaskCreationOptions.LongRunning选项,展示了如何确保即使线程池资源紧张,也能确保任务得以执行。实验表明,正确设置该选项可以使得任务运行不受线程池限制,从而允许服务同时处理更多客户端的监听请求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


最近在学WebSocket,服务端需要监听多个WebSocket客户端发送的消息。

开始的解决方法是每个WebSocket客户端都添加一个线程进行监听,代码如下:

/// <summary>
/// 监听端口 创建WebSocket
/// </summary>
/// <param name="httpListener"></param>
private void CreateWebSocket(HttpListener httpListener)
{
    if (!httpListener.IsListening)
        throw new Exception("HttpListener未启动");
    HttpListenerContext listenerContext =  httpListener.GetContextAsync().Result;

    if (!listenerContext.Request.IsWebSocketRequest)
    {
        CreateWebSocket(httpListener);
        return;
    }

    WebSocketContext webSocket = null;
    try
    {
        webSocket = new WebSocketContext(listenerContext, SubProtocol);
    }
    catch (Exception ex)
    {
        log.Error(ex);
        CreateWebSocket(HttpListener);
        return;
    }

    log.Info($"成功创建WebSocket:{webSocket.ID}");

    int workerThreads = 0, completionPortThreads = 0;
    ThreadPool.GetAvailableThreads(out workerThreads, out completionPortThreads);
    if (workerThreads <= ReservedThreadsCount + 1 || completionPortThreads <= ReservedThreadsCount + 1)
    {
        /**
         * 可用线程小于预留线程数量
         * 通知客户端关闭连接
         * */
        webSocket.CloseAsync(WebSocketCloseStatus.InternalServerError, "可用线程不足,无法连接").Wait();
    }
    else
    {
        if (OnReceiveMessage != null)
            webSocket.OnReceiveMessage += OnReceiveMessage;
        webSocket.OnCloseWebSocket += WebSocket_OnCloseWebSocket;
        webSocketContexts.Add(webSocket);

        // 在线程中监听客户端发送的消息
        ThreadPool.QueueUserWorkItem(new WaitCallback(p =>
        {
            (p as WebSocketContext).ReceiveMessageAsync().Wait();
        }), webSocket);

    }

    CreateWebSocket(HttpListener);
}
在线程中添加监听代码

 

但是可用线程数量是有限的,先连接的客户端一直递归接收消息,导致线程无限占用,后连接上的客户端就没有线程用于监听接受消息了。
接受消息方法如下:

/// <summary>
/// 递归 同步接收消息
/// </summary>
/// <returns></returns>
public void ReceiveMessage()
{
    WebSocket webSocket = HttpListenerWebSocketContext.WebSocket;

    if (webSocket.State != WebSocketState.Open)
        throw new Exception("Http未握手成功,不能接受消息!");
    
    var byteBuffer = WebSocket.CreateServerBuffer(ReceiveBufferSize);
    WebSocketReceiveResult receiveResult = null;
    try
    {
        receiveResult = webSocket.ReceiveAsync(byteBuffer, cancellationToken).Result;
    }
    catch (WebSocketException ex)
    {
        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值