首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >特定情况下的C# Dispose()标准

特定情况下的C# Dispose()标准
EN

Stack Overflow用户
提问于 2019-10-06 09:14:05
回答 1查看 321关注 0票数 0

我们知道Dispose(bool disposing)应该是受保护的或私有的,如果我需要手动释放未管理的资源怎么办?接口IDISPOSIBLE中的Dispose()必须调用Dispose(true),这意味着释放所有资源。我想手动控制管理和非管理资源的释放。

实现Dispose的官方方式是https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/implementing-dispose。但是,有时我需要使用Dispose(false)手动释放某些资源,该函数是否应该是公共函数,或者我是否需要创建另一个函数(如DisposeUnManage() )来手动释放未管理的资源?

代码语言:javascript
复制
public void Dispose()
   { 
      Dispose(true);
      GC.SuppressFinalize(this);           
   }

  protected virtual void Dispose(bool disposing)
   {
      if (disposed)
         return; 

      if (disposing) {
         handle.Dispose();
         // Free any other managed objects here.

      }

      disposed = true;
   }
代码语言:javascript
复制
public void Dispose()
   { 
      Dispose(true);
      GC.SuppressFinalize(this);           
   }

public void DisposeUnmanage()
{
Dispose(false);
}

private void Dispose(bool disposing)
   {
      if (disposed)
         return; 

      if (disposing) {
         handle.Dispose();
         // Free any other managed objects here.

      }

      disposed = true;
   }

与TCPStream中的代码类似,当TCP客户端断开连接时,我需要使用这个TCPStream.Dispose(false)方法。当我的TCPServer关闭时,我应该调用TCPStream.Dispose(true)。

代码语言:javascript
复制
/// <summary>
        /// Closes the underlying socket
        /// </summary>
        /// <param name="disposing">
        /// If true, the EventArg objects will be disposed instead of being re-added to 
        /// the IO pool. This should NEVER be set to true unless we are shutting down the server!
        /// </param>
        private void Dispose(bool disposeEventArgs = false)
        {
            // Set that the socket is being closed once, and properly
            if (SocketClosed) return;
            SocketClosed = true;

            // If we need to dispose out EventArgs
            if (disposeEventArgs)
            {
                ReadEventArgs.Dispose();
                WriteEventArgs.Dispose();
                DisposedEventArgs = true;
            }
            else
            {
                // Finally, release this stream so we can allow a new connection
                SocketManager.Release(this);
                Released = true;
            }

            // Do a shutdown before you close the socket
            try
            {
                Connection.Shutdown(SocketShutdown.Both);
            }
            catch (Exception) { }
            finally
            {
                // Unregister for vents
                ReadEventArgs.Completed -= IOComplete;
                WriteEventArgs.Completed -= IOComplete;

                // Close the connection
                Connection.Close();
                Connection = null;
            }           

            // Call Disconnect Event
            if (!DisconnectEventCalled && OnDisconnected != null)
            {
                DisconnectEventCalled = true;
                OnDisconnected();
            }
        }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-10-07 00:15:45

很明显,您滥用了一次性模式。

Dispose(bool disposing)意味着当对象不再需要并且永远不会再被使用时,只调用一次。这可能是因为有人直接调用了Dispose() (它调用了Dispose(true)),或者因为对象的终结器运行了(它调用了Dispose(false))。此外,正如@Dmytro Mukalov指出的那样,在Dispose(false)期间使用托管对象是不安全的,并且可能导致难以调试的问题(但只有当您的对象实际具有终结器时才适用)。

如果您正在尝试实现对象池,我建议您创建一个池服务,然后将其注入到此TCPStream中。它将管理池化对象的生命周期,并允许RentReturn操作。然后,TCPStream.Dispose()Return任何以前被Rent的对象,并摆脱它自己的资源,而实际的池化对象只会在池化服务被释放时被释放(您可以将其设置为在TCPServer关闭时)。按照现在的情况,您的TCPStream有太多的责任,这会阻止您正确地实现可处理模式。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58253518

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档