为了账号安全,请及时绑定邮箱和手机立即绑定

在C#中完成/处理模式

在C#中完成/处理模式

慕田峪4524236 2019-06-17 16:41:18
在C#中完成/处理模式C#2008我在这方面的工作已经有一段时间了,我仍然对一些问题感到困惑。我的问题如下我知道,只有在处理非托管资源时才需要终结器。但是,如果使用调用非托管资源的托管资源,还需要实现终结器吗?但是,如果您开发的类不直接或间接地使用任何非托管资源,那么您能否实现IDisposable以便您的类的客户端可以使用“Using语句”?实现IDisposable只是为了使您的类的客户端能够使用Using语句,这是否是可以接受的?using(myClass objClass = new myClass()){     // Do stuff here}我在下面开发了这个简单的代码来演示Finish/Dispose模式:public class NoGateway : IDisposable{     private WebClient wc = null;     public NoGateway()     {         wc = new WebClient();         wc.DownloadStringCompleted += wc_DownloadStringCompleted;     }     // Start the Async call to find if NoGateway is true or false     public void NoGatewayStatus()     {         // Start the Async's download             // Do other work here         wc.DownloadStringAsync(new Uri(www.xxxx.xxx));     }     private void wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)     {         // Do work here     }     // Dispose of the NoGateway object     public void Dispose()     {         wc.DownloadStringCompleted -= wc_DownloadStringCompleted;         wc.Dispose();         GC.SuppressFinalize(this);     }}关于源代码的问题:这里我没有添加终结器,通常情况下,终结器将由GC调用,终结器将调用Dispose。由于我没有终结器,什么时候调用Dispose方法?是必须调用它的类的客户端吗?因此,我在示例中的类名为NoGateway,客户机可以像这样使用和处理该类:using(NoGateway objNoGateway = new NoGateway()){     // Do stuff here   }当执行到达Using块的末尾时,是否会自动调用Dispose方法,或者客户端是否必须手动调用Dispose方法?E.NoGateway objNoGateway = new NoGateway();// Do stuff with objectobjNoGateway.Dispose(); // finished with it我在我的NoGateway班级,等级。因为WebClient实现了IDisposable接口,这是否意味着WebClient间接使用非托管资源?在这方面是否有严格的规则可以遵循?如何知道类使用非托管资源?
查看完整描述

3 回答

?
达令说

TA贡献1821条经验 获得超6个赞

官方实施模式IDisposable很难理解。我相信这个是更好:

public class BetterDisposableClass : IDisposable {

  public void Dispose() {
    CleanUpManagedResources();
    CleanUpNativeResources();
    GC.SuppressFinalize(this);
  }

  protected virtual void CleanUpManagedResources() { 
    // ...
  }
  protected virtual void CleanUpNativeResources() {
    // ...
  }

  ~BetterDisposableClass() {
    CleanUpNativeResources();
  }}

更好解决办法是制定一条规则必须为需要处理的任何非托管资源创建包装类:

public class NativeDisposable : IDisposable {

  public void Dispose() {
    CleanUpNativeResource();
    GC.SuppressFinalize(this);
  }

  protected virtual void CleanUpNativeResource() {
    // ...
  }

  ~NativeDisposable() {
    CleanUpNativeResource();
  }}

带着SafeHandle以及它的导数,这些类应该是非常罕见.

对于不直接处理非托管资源的一次性类,即使在存在继承的情况下,结果也是强大的:他们不需要再关心非托管资源了..他们会简约执行和理解:

public class ManagedDisposable : IDisposable {

  public virtual void Dispose() {
    // dispose of managed resources
  }}


查看完整回答
反对 回复 2019-06-17
  • 3 回答
  • 0 关注
  • 429 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信