我的 c# 8.0 using 声明会正确处理我的对象吗?什么时候处置?

Will my c# 8.0 using declaration dispose my object correctly? When is it disposed?

当它为真时,我在循环中调用以下方法,这导致自动重新连接。由于我使用的是 using 关键字,它是在每个 try/catch return false 上处理 ClientWebSocket 还是只处理它 如果 它到达 ConnectAsync 的末尾?

private async Task<bool> ConnectAsync(CancellationToken cancellationToken)
{
    using var clientWebSocket = new ClientWebSocket(); // TODO: Check if it's actually disposed
    _clientWebSocket = clientWebSocket;

    try
    {
        await clientWebSocket.ConnectAsync(new Uri(_url), cancellationToken);
    }
    catch
    {
        return false;
    }

    try
    {
        while (clientWebSocket.State == WebSocketState.Open && !cancellationToken.IsCancellationRequested)
        {
            var bytesReceived = new ArraySegment<byte>(new byte[1024]);
            var receiveResult = await clientWebSocket.ReceiveAsync(bytesReceived, cancellationToken);
            var message = Encoding.UTF8.GetString(bytesReceived.Array, 0, receiveResult.Count);
            
            ...
        }
    }
    catch
    {
        return false;
    }

    try
    {
        if (clientWebSocket.State == WebSocketState.Open)
        {
            await clientWebSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "bye", CancellationToken.None);
        }
    }
    catch
    {
        return false;
    }

    return true;
}

The using declaration calls the Dispose method on the object in the correct way when it goes out of scope. From: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-statement#remarks

所以,简而言之。当方法 returns 时,它将处理 using 声明。

如果你想测试这个,你可以创建一个继承 ClientWebSocket 的 class,你可以创建你自己的处理覆盖来做一些日志记录。

using var clientWebSocket = new ClientWebSocket();只是语法糖,它是

的简写
private async Task<bool> ConnectAsync(CancellationToken cancellationToken)
{
    using( var clientWebSocket = new ClientWebSocket())
    {
        _clientWebSocket = clientWebSocket;

        try
        {
            await clientWebSocket.ConnectAsync(new Uri(_url), cancellationToken);
        }
        catch
        {
            return false;
        }

        try
        {
            while (clientWebSocket.State == WebSocketState.Open && !cancellationToken.IsCancellationRequested)
            {
                var bytesReceived = new ArraySegment<byte>(new byte[1024]);
                var receiveResult = await clientWebSocket.ReceiveAsync(bytesReceived, cancellationToken);
                var message = Encoding.UTF8.GetString(bytesReceived.Array, 0, receiveResult.Count);
                
                ...
            }
        }
        catch
        {
            return false;
        }

        try
        {
            if (clientWebSocket.State == WebSocketState.Open)
            {
                await clientWebSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "bye", CancellationToken.None);
            }
        }
        catch
        {
            return false;
        }

        return true;

    }
}

这是以下简称:

private async Task<bool> ConnectAsync(CancellationToken cancellationToken)
{
    var clientWebSocket = new ClientWebSocket();
    try
    {
        _clientWebSocket = clientWebSocket;

        try
        {
            await clientWebSocket.ConnectAsync(new Uri(_url), cancellationToken);
        }
        catch
        {
            return false;
        }

        try
        {
            while (clientWebSocket.State == WebSocketState.Open && !cancellationToken.IsCancellationRequested)
            {
                var bytesReceived = new ArraySegment<byte>(new byte[1024]);
                var receiveResult = await clientWebSocket.ReceiveAsync(bytesReceived, cancellationToken);
                var message = Encoding.UTF8.GetString(bytesReceived.Array, 0, receiveResult.Count);
                
                ...
            }
        }
        catch
        {
            return false;
        }

        try
        {
            if (clientWebSocket.State == WebSocketState.Open)
            {
                await clientWebSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "bye", CancellationToken.None);
            }
        }
        catch
        {
            return false;
        }

        return true;

    }
    finally
    {
        if (clientWebSocket != null) {
            ((IDisposable)clientWebSocket).Dispose();  
        }
    }
}

我觉得也值得:

I'm more worried that you're disposing something that you've assigned to the field _clientWebSocket

clientWebSocket 将被处置,但是因为您将 _clientWebSocket 分配给此 (_clientWebSocket = clientWebSocket;),varibale 指向的对象将被处置还有!他们是一样的东西。他们互相参考。我想这不是您想在这里发生的事情,但很难从您共享的代码中分辨出来。