gpt4 book ai didi

c# - 在这种情况下,避免ObjectDisposedException的正确方法是?

转载 作者:行者123 更新时间:2023-12-03 07:44:20 25 4
gpt4 key购买 nike

我当前在下一行上收到一个ObjectDisposedException。

var client = ((Socket) asyncResult.AsyncState).EndAccept(asyncResult);

System.ObjectDisposedException: 'Cannot access a disposed object. Object name: 'System.Net.Sockets.Socket'.'



我只是想知道,避免这种错误的正确方法(按照最佳实践)是什么?我不确定如何处理它,如何检查它是否已预先处置,但是我应该做什么?或检查其他内容。

我是自学C#,所以我从没学过类似的东西,有人可以提供一些见解吗?

这是完整的类(class):
internal sealed class SocketHandler : IDisposable
{
private static readonly ILogger Logger = LogManager.GetCurrentClassLogger();

private readonly Socket _serverSocket;

public SocketHandler()
{
_serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

Load();
}

public void Dispose()
{
_serverSocket?.Close(); // close also calls dispose...
}

private void Load()
{
var config = Program.Server.ConfigHandler;

_serverSocket.Bind(new IPEndPoint(IPAddress.Any, config.GetConfigValueByKey("network.sockets.port").ToInt()));
_serverSocket.Listen(int.Parse(config.GetConfigValueByKey("network.sockets.backlog")));
_serverSocket.BeginAccept(OnAcceptConnection, _serverSocket);
}

private void OnAcceptConnection(IAsyncResult asyncResult)
{
try
{
if (_serverSocket == null)
{
return;
}

var client = ((Socket) asyncResult.AsyncState).EndAccept(asyncResult);

var playerHandler = Program.Server.BaseHandler.PlayerHandler;
var players = playerHandler.Players;

var config = Program.Server.ConfigHandler;

var maxConnections = int.Parse(config.GetConfigValueByKey("game.players.limit"));
var maxConnectionsPerIp = int.Parse(config.GetConfigValueByKey("game.players.ip_limit"));

if (players.Count >= maxConnections)
{
Logger.Warn("Incoming connection was refused because the player limit was exceeded.");

client.Shutdown(SocketShutdown.Both);
client.Close();

return;
}

if (players.Values.Count(x => x != null && !x._disconnected && x.getIp() == client.RemoteEndPoint.ToString().Split(':')[0]) > maxConnectionsPerIp)
{
Logger.Warn("Incoming connection was refused because the IP limit was exceeded.");

client.Shutdown(SocketShutdown.Both);
client.Close();

return;
}

var clientId = Randomizer.Next(1, 10000);

Program.Server.BaseHandler.PlayerHandler.TryAddPlayer(clientId, new Player(clientId, client, new InitialPacketParser()));
}
catch (SocketException socketException)
{
Logger.Fatal(socketException, "Failed to accept socket connection.");
}
finally
{
_serverSocket?.BeginAccept(OnAcceptConnection, _serverSocket);
}
}
}

最佳答案

据我了解reference sourceSocket本身不是Dispose。因此,由于您的_serverSocketprivate,因此您是唯一可以控制其处置时间的人。

您的OnAcceptConnection()方法已经开始尝试进行检查,但还不是完全。

Dispose()方法(或Close()Dispose() _serverSocket的任何其他位置)中,您还需要将_serverSocket设置为null。您可以通过线程安全的方式执行以下操作:

public class SocketHandler
{
private Socket _serverSocket; // not read-only

/* ... */

public void Dispose()
{
Socket tmp = _serverSocket; // save instance
_serverSocket = null; // set field to null
tmp?.Close();
}

现在,您的 OnAcceptConnection()在检查 if (_serverSocket == null)时返回,因此可以避免该异常。

关于c# - 在这种情况下,避免ObjectDisposedException的正确方法是?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48402028/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com