C#正确使用安全带进行处理
我知道并希望正确处理我的套接字资源。 在他们推荐使用的文档中,但我不确定这是如何使用的。我发现Socket类本身包含一个,但我不知道如何使用它。我是否需要处理把手和插座,或者仅处理把手就足够了?我假设在这个类中,我只对套接字操作使用句柄,对吗C#正确使用安全带进行处理,c#,sockets,dispose,finalizer,C#,Sockets,Dispose,Finalizer,我知道并希望正确处理我的套接字资源。 在他们推荐使用的文档中,但我不确定这是如何使用的。我发现Socket类本身包含一个,但我不知道如何使用它。我是否需要处理把手和插座,或者仅处理把手就足够了?我假设在这个类中,我只对套接字操作使用句柄,对吗 public class MySocket : IDisposable { private SafeSocketHandle _handle; private bool _disposed = false; public MySo
public class MySocket : IDisposable
{
private SafeSocketHandle _handle;
private bool _disposed = false;
public MySocket(AddressFamily addressFamily)
{
Socket s = new Socket(addressFamily, SocketType.Stream, ProtocolType.Tcp);
_handle = s.SafeHandle;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (_disposed)
return;
if (disposing)
{
_handle.Dispose();
}
_disposed = true;
}
}
也许有人也能解释为什么应该使用安全手柄?
我的意思是,这还不够吗
public class MySocket : IDisposable
{
private Socket _socket;
private bool _disposed = false;
public MySocket(AddressFamily addressFamily)
{
_socket = new Socket(addressFamily, SocketType.Stream, ProtocolType.Tcp);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (_disposed)
return;
if (disposing)
{
_socket.Dispose();
}
_disposed = true;
}
}
直接管理非托管资源时,应使用
安全句柄
对于Socket
,有一个底层非托管资源,但它由Socket
类处理。您无需参与其中--Socket
本身是一个托管资源,而不是非托管资源<代码>套接字
有自己的终结器,如果您忘记处置底层非托管资源,它将(可能)释放该资源
因此,在这里,您不需要担心安全句柄
。只需实现IDisposable并调用socket.Dispose()
您不需要在这里实现完整的Dispose模式,除非您可能有一个拥有自己的非托管资源的派生类。写下以下内容就足够了:
public class MySocket : IDisposable
{
private Socket _socket;
private bool _disposed = false;
public MySocket(AddressFamily addressFamily)
{
_socket = new Socket(addressFamily, SocketType.Stream, ProtocolType.Tcp);
}
public void Dispose()
{
_socket.Dispose();
_disposed = true;
}
}
事实上,许多编码标准要求非托管资源必须包装在安全句柄
中。如果您这样做,就不需要实现完整的Dispose模式
如果确实需要实现完整的dispose模式,那么还需要编写终结器。你问题中的代码没有做到这一点
事实上,dispose模式会让用户走上一条非常危险的道路——在
void dispose(bool disposing)
方法中编写正确的代码确实非常困难,而且存在许多用户没有意识到的陷阱。这就是为什么.NET 2.0中引入了SafeHandle
——运行时对它有特殊的支持,可以避免这些陷阱——但是关于IDisposable
的建议似乎从未更新过。请注意,您已经错过了代码示例中的终结器——它们很重要。@canton7不是模式的漏洞避免直接使用终结器?在本例中,它们也没有实现终结器:SafeHandle
的目的是避免用户在尝试释放非托管资源时自食其果。如果您使用的是SafeHandle
,您确实不需要实现完整的dispose模式,请参阅我的答案。但是,如果要实现完整的dispose模式,则需要正确地执行。在您的代码中,GC.SuppressFinalize(this)
什么都不做(因为您没有终结器),并且没有任何东西会使用false
调用您的void Dispose(bool disposing)
方法。现在我更清楚了。谢谢所以基本上我可以使用SafeHandle来避免实现终结器。但因为套接字负责非托管资源,所以我不需要安全句柄。因此,简单的处理就足够了。但是,您能帮我一个忙,非常简单地解释一下,在这种情况下,非托管资源是什么,以及套接字是如何处理它们的?这将有助于我将来决定是否需要一个SafeHandle,SafeHandle
的作用不仅仅是让您避免编写终结器:它避免了释放非托管资源时的一些陷阱。例如,您知道您的类可以在它的一个方法执行时完成吗?这意味着您可以在本机函数使用句柄时关闭它,这是非常糟糕的<代码>套接字是一个特别复杂的例子--文件流
要简单得多,看看\u handle
是如何使用的。