如果一个对象使用 'using' 并且它被用在一些方法中,什么时候被释放
When is an object disposed if it uses 'using' and it is being used in a few methods
查看下面 class 中的这一特定代码行:using var ws = new ClientWebSocket()
。考虑到它使用 using
并且它被用于一些更像 SendAsync、ReceiveAsync 等的方法,该对象何时被处置?如果它是在像 Main() 这样的常规方法中,它通常会在结束分支处被释放,但在这种情况下它不会被释放在那里。此 class 也不继承 IDisposable
。我从 class.
中删除了不必要的细节
public class Client
{
private ClientWebSocket? _ws;
private async Task<bool> ConnectAsync(CancellationToken cancellationToken)
{
using var ws = new ClientWebSocket();
_ws = ws;
...
}
public async Task SendAsync(string data)
{
...
await _ws.SendAsync(dataBytes, WebSocketMessageType.Text, true, CancellationToken.None);
}
}
您的 using
语句是 C# 在 C# version 8 中引入的新的 using 声明样式,这意味着您的语句不再有不必要的嵌套。然而,原则仍然是一样的。考虑以下在 C# 8 之前编写代码的方式:
public class Client
{
private ClientWebSocket? _ws;
private async Task<bool> ConnectAsync(CancellationToken cancellationToken, string data)
{
using (var ws = new ClientWebSocket())
{
// When your code leaves this block, your websocket is disposed
ws.SendAsync(dataBytes, WebSocketMessageType.Text, true, CancellationToken.None);
// Assigning ws to _ws isn't necessary as it isn't usable outside your using statement
_ws = ws;
// The end of your using block - the websocket will now be disposed
}
// This line would fail as your websocket has been disposed
_ws.SendAsync(dataBytes, WebSocketMessageType.Text, true, CancellationToken.None);
}
}
当您的代码离开 using 块时,将调用 dispose 方法。声明意味着它被处理后的范围现在是包含 using 声明的代码块,在本例中是您的 ConnectAsync
方法。因此,即使在将它分配给 _ws 时您仍然引用它,它也不能使用,因为当您的代码离开此方法块时它已经被释放。
查看下面 class 中的这一特定代码行:using var ws = new ClientWebSocket()
。考虑到它使用 using
并且它被用于一些更像 SendAsync、ReceiveAsync 等的方法,该对象何时被处置?如果它是在像 Main() 这样的常规方法中,它通常会在结束分支处被释放,但在这种情况下它不会被释放在那里。此 class 也不继承 IDisposable
。我从 class.
public class Client
{
private ClientWebSocket? _ws;
private async Task<bool> ConnectAsync(CancellationToken cancellationToken)
{
using var ws = new ClientWebSocket();
_ws = ws;
...
}
public async Task SendAsync(string data)
{
...
await _ws.SendAsync(dataBytes, WebSocketMessageType.Text, true, CancellationToken.None);
}
}
您的 using
语句是 C# 在 C# version 8 中引入的新的 using 声明样式,这意味着您的语句不再有不必要的嵌套。然而,原则仍然是一样的。考虑以下在 C# 8 之前编写代码的方式:
public class Client
{
private ClientWebSocket? _ws;
private async Task<bool> ConnectAsync(CancellationToken cancellationToken, string data)
{
using (var ws = new ClientWebSocket())
{
// When your code leaves this block, your websocket is disposed
ws.SendAsync(dataBytes, WebSocketMessageType.Text, true, CancellationToken.None);
// Assigning ws to _ws isn't necessary as it isn't usable outside your using statement
_ws = ws;
// The end of your using block - the websocket will now be disposed
}
// This line would fail as your websocket has been disposed
_ws.SendAsync(dataBytes, WebSocketMessageType.Text, true, CancellationToken.None);
}
}
当您的代码离开 using 块时,将调用 dispose 方法。声明意味着它被处理后的范围现在是包含 using 声明的代码块,在本例中是您的 ConnectAsync
方法。因此,即使在将它分配给 _ws 时您仍然引用它,它也不能使用,因为当您的代码离开此方法块时它已经被释放。