2

因此,当我关闭表单时,我目前正在处理许多对象。即使它可能会自动处理它。但我仍然更喜欢在处理时遵循“规则”,希望它会坚持并有助于防止错误。

所以这就是我目前的处理方式,它有效。

        if (connect == true)
        {
            Waloop.Dispose();
            connect = false;
            UninitializeCall();
            DropCall();

        }
        if (KeySend.Checked || KeyReceive.Checked)
        {
            m_mouseListener.Dispose();
            k_listener.Dispose();

        }
        if (NAudio.Wave.AsioOut.isSupported())
        {
            Aut.Dispose();
        }

        if (Wasout != null)
        {
            Wasout.Dispose();
        }
        if (SendStream != null)
        {
            SendStream.Dispose();
        }

所以基本上,第一个是如果一个布尔值是真的,这意味着如果不是,那些可以被忽略,因为我认为它们还没有被制造出来。

如果它在那里,其他的只是我处理的方式。但这不是一个很好的方法,我希望它具有 1 个大功能,意思是。

如果没有处置,请处置。或者其他的东西。我知道他们中的许多人都有“isdisposed”布尔值,所以如果我可以检查每个对象,并且如果它是假的,就应该处理它。

4

4 回答 4

5

将对象IDisposable作为参数实现的辅助方法怎么样?

void DisposeAll(params IDisposable[] disposables)
{
  foreach (IDisposable id in disposables)
  {
    if (id != null) id.Dispose();
  }
}

当您想要处置多个对象时,请使用您想要处置的任何对象调用该方法。

this.DisposeAll(Wasout, SendStream, m_mouseListener, k_listener);

如果您想避免显式调用它们,请将它们全部存储在 a 中List<>

private List<IDisposable> _disposables;

void DisposeAll() {
  foreach(IDisposable id in _disposables) {
    if(id != null) id.Dispose();
  }
}
于 2013-08-15T13:46:43.380 回答
2

您可以按照Disposer以下方式实现一个类,它将为您完成工作:

public class Disposer
{
   private List<IDisposable> disposables = new List<IDisposable>();

   public void Register(IDisposable item)
   {
      disposables.Add(item);
   }

   public void Unregister(IDisposable item)
   {
      disposables.Remove(item);
   }

   public void DisposeAll()
   {
      foreach (IDisposable item in disposables)
      {
        item.Dispose();
      }
      disposables.Clear();
   }
}

然后,代替主类中丑陋的代码,您可以使用以下内容:

public class Main
{
   //member field
   private Disposer m_disposer;

   //constructor
   public Main()
   {
       ....
       m_disposer = new Disposer();
       //register any available disposables
       disposer.Register(m_mouseListener);
       disposer.Register(k_listener);
   }

   ...

   public bool Connect()
   {
       ...
       if (isConnected)
       {
           Waloop = ...
           Wasout = ...
           // register additional disposables as they are created
           disposer.Register(Waloop);
           disposer.Register(Wasout);
       }
   }

   ...

   public void Close()
   {
     //disposal
     disposer.DisposeAll();
   }
}
于 2013-08-15T14:07:20.473 回答
1

我建议你使用using 语句。因此,使用您的代码,它看起来像这样:

  using (WaloopClass Waloop = new WaloopClass())
  {
        // Some other code here I know nothing about.

        connect = false; // Testing the current value of connect is redundant.
        UninitializeCall();
        DropCall();
  }

请注意,现在不需要显式 Dispose Waloop,因为它会在 using 语句的末尾自动发生。

这将有助于构建您的代码,并使 Waloop 的范围更加清晰。

于 2013-08-15T13:49:53.390 回答
1

我将假设您要解决的唯一问题是如何以更好的方式编写以下内容:

if (Wasout != null)
    Wasout.Dispose();
if (SendStream != null)
    SendStream.Dispose();

这是using关键字已经实现的很多逻辑。在调用您之前using检查变量是否不Dispose()为空。此外,using保证抛出的异常(可能由Wasout.Dispose())不会中断Dispose()对其他列出的对象(例如SendStream)的调用尝试。这似乎using是为了允许基于范围规则管理资源:使用using作为替代的写作方式o.Dispose()可能被认为是对语言的滥用。然而, 的using行为的好处和它所带来的简洁是非常有价值的。因此,我建议将“<code>if (o != null) o.Dispose()”的大量静态写入批次替换为“empty” using

using (
    IDisposable _Wasout = Wasout,
    _SendStream = SendStream)
{}

请注意,调用的顺序与块Dispose()中对象的列出方式相反。using这遵循以与实例化顺序相反的方式清理对象的模式。(想法是,稍后实例化的对象可能指代较早实例化的对象。例如,如果您正在使用梯子爬房子,您可能希望保留梯子,这样您就可以在收起之前爬回去——梯子首先被实例化,最后被清理。嗯,类比......但是,基本上,上面是嵌套的简写using。不同的对象可以using通过编写usingin 来粉碎到同一个块中IDisposable。)

dotnetfiddleusing管理异常。

于 2014-02-19T15:57:08.440 回答