我应该在Task中循环还是直接在accept过程中循环?

问题描述 投票:0回答:1

我正在尝试在 .NET 中使用 Websockets(不是信号器),我发现这篇文章很有用。

public class WSHandler : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        if (context.IsWebSocketRequest)
        {
            context.AcceptWebSocketRequest(ProcessWSChat);
        }
    }

    public bool IsReusable { get { return false; } }

    private async Task ProcessWSChat(AspNetWebSocketContext context)
    {
        WebSocket socket = context.WebSocket;
        while (true)
        {
            ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[1024]);
            WebSocketReceiveResult result = await socket.ReceiveAsync(
                buffer, CancellationToken.None);
            if (socket.State == WebSocketState.Open)
            {
                string userMessage = Encoding.UTF8.GetString(
                    buffer.Array, 0, result.Count);
                userMessage = "You sent: " + userMessage + " at " + 
                    DateTime.Now.ToLongTimeString();
                buffer = new ArraySegment<byte>(
                    Encoding.UTF8.GetBytes(userMessage));
                await socket.SendAsync(
                    buffer, WebSocketMessageType.Text, true, CancellationToken.None);
            }
            else
            {
                break;
            }
        }
    }
}

但是,我对处理函数感到困惑

  1. 我应该在处理程序中执行
    while (true)
    还是返回任务?例如
    return new Task(() => { ... })
  2. 我尝试了第二种方法,循环没有执行。如果我应该在处理程序内执行循环,那么为什么此方法使用 Task 作为返回类型?
c# websocket task
1个回答
0
投票

我建议在你的方法中使用 CancellationToken,就像这样

private async Task ProcessWSChat(AspNetWebSocketContext context, CancellationToken cancellationToken)

您应该能够从

HttpContext context
RequestAborted
属性下访问 CT。

然后你的while条件可以改为

while(!cancellationToken.IsCancellationRequested)
{
   ...
}

因此,此代码将运行,直到应用程序或用户以某种方式决定停止它(例如将停止应用程序或代码的其他部分将升级操作取消。通常,这是所有异步操作的一种方式,应该考虑取消令牌整个操作链,从顶层到底层:)

© www.soinside.com 2019 - 2024. All rights reserved.