猿问

在C#中完成/处理模式

在C#中完成/处理模式

C#2008

我在这方面的工作已经有一段时间了,我仍然对一些问题感到困惑。我的问题如下

  1. 我知道,只有在处理非托管资源时才需要终结器。但是,如果使用调用非托管资源的托管资源,还需要实现终结器吗?

  2. 但是,如果您开发的类不直接或间接地使用任何非托管资源,那么您能否实现IDisposable以便您的类的客户端可以使用“Using语句”?

    实现IDisposable只是为了使您的类的客户端能够使用Using语句,这是否是可以接受的?

    using(myClass objClass = new myClass()){
        // Do stuff here}
  3. 我在下面开发了这个简单的代码来演示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);
        }}

关于源代码的问题:

  1. 这里我没有添加终结器,通常情况下,终结器将由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
  2. 我在我的NoGateway班级,等级。因为WebClient实现了IDisposable接口,这是否意味着WebClient间接使用非托管资源?在这方面是否有严格的规则可以遵循?如何知道类使用非托管资源?


慕田峪4524236
浏览 430回答 3
3回答

达令说

官方实施模式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   }}
随时随地看视频慕课网APP
我要回答