C# 大规模处置,更好的方式?

C# 大规模处置,更好的方式?,c#,dispose,C#,Dispose,因此,当我关闭表单时,我正在处理许多对象。即使它可能会自动处理它。但我还是更喜欢按照“规则”处理,希望它能坚持下去,有助于防止错误 下面是我目前的处理方式,它是有效的 if (connect == true) { Waloop.Dispose(); connect = false; UninitializeCall(); DropCall(); }

因此,当我关闭表单时,我正在处理许多对象。即使它可能会自动处理它。但我还是更喜欢按照“规则”处理,希望它能坚持下去,有助于防止错误

下面是我目前的处理方式,它是有效的

        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();
        }
因此,基本上,第一个是如果一个布尔是真的,也就是说,如果它不是真的,那么这些可以忽略,因为我认为它们还没有被制造出来

其他的都是我处理的方法,如果有的话。但这不是一个很好的方法,我希望它有一个大的功能,意思是

如果未处理,则处理。或者别的什么。
我知道他们中的许多人都有“isdisposed”bool,所以如果我可以检查每个对象,如果它是假的,就可以处理它。

一个助手方法如何,它将实现
IDisposable
的对象作为参数

void DisposeAll(params IDisposable[] disposables)
{
  foreach (IDisposable id in disposables)
  {
    if (id != null) id.Dispose();
  }
}
当您要处理多个对象时,请使用您要处理的任何对象调用该方法

this.DisposeAll(Wasout, SendStream, m_mouseListener, k_listener);
如果您不想明确地调用它们,请将它们全部存储在
列表中

private List\u一次性用品;
无效处置{
foreach(一次性设备中的IDisposable id){
如果(id!=null)id.Dispose();
}
}
我建议您使用。因此,对于您的代码,它看起来是这样的:

  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();
  }
注意,现在不需要显式地处理Waloop,因为它会自动发生在using语句的末尾


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

您可以实现一个
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();
   }
}

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

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

using (
    IDisposable _Wasout = Wasout,
    _SendStream = SendStream)
{}
请注意,调用
Dispose()
的顺序与使用
块在
中列出对象的顺序相反。这遵循与实例化顺序相反的清理对象的模式。(其想法是,稍后实例化的对象可能指的是之前实例化的对象。例如,如果您使用梯子爬房子,您可能希望保持梯子在周围,以便您可以在放下梯子之前爬回。梯子首先实例化,最后清理。嗯,类似于……但基本上,上面是。和使用
块,通过使用
IDisposable中写入
,可以将不同的对象粉碎到相同的
块中



您的意思是,当我关闭表单时,整个应用程序将在
关闭吗?如果是这样,那就简单-什么也不做。@asawyer:这很容易,直到6个月后他决定这个表单不应该是他的主要表单,突然他泄露了句柄。是的,正如吉姆所说,这就是为什么我要做好准备:)@JimMischel你必须知道你的资源集中在哪里。如果可能性很大,当然可以。如果没有,请转到其他内容。你必须在某个地方取得平衡。不要写无意义的代码。从文档中找出一个对象是否是一次性的,以及它是否已经被处理掉,没有必要去猜测它。如果这是一个表单,而对象不是控件或组件,那么很有可能您必须自己处理它。+1有趣的想法,我一直忘记
params
关键字。我不知道如何实现它,但它看起来非常像我从这里得到的调用器方法。你能演示一下如何向它添加一个对象以供使用吗?啊,有可能像我的Invoker方法那样做吗。Invoker(()=>{})?这是一个答案,尽管我希望能够不用逗号来编写它,更像(Sendstream;“tab”Wasaout;)在某些情况下使用语句是有意义的,但并非所有时候我都在尽可能多地使用Using语句,因为它有性能优势,大多数时候都是这样,但正如Simon所说,不是所有的时间。我知道如何使用,最近才学会,并且尽可能经常地使用:)但是,我必须在创建时将我想处理的所有东西都注册到处理程序中?不过,这看起来会更干净。如果是A+,就试试看。@user2587718:不一定。您可以将disposer作为一个成员变量,并根据需要注册和取消注册。不知道如何做到这一点,我已经在private disposer blabla中添加了它。我现在正在注册你所做的一切。好吧,它似乎不起作用,我得到的对象引用没有设置为对象的实例,可能是因为它没有访问变量的权限。尝试将它们更改为public,但没有帮助,因为如果您不介意使用threadstatic变量,您可以定义一个
t RegisterDisposable(t it),其中t:IDisposable
函数并在对象初始值设定项中使用它(例如
var MyBrush=RegisterDisposable(new SolidBrush());
)。Threadstatic变量令人讨厌,但上述方法可以轻松确保变量得到初始化和清理。VB.NET允许消除threadstatic变量,但我不知道如何在C#中这样做。
if (Wasout != null)
    Wasout.Dispose();
if (SendStream != null)
    SendStream.Dispose();
using (
    IDisposable _Wasout = Wasout,
    _SendStream = SendStream)
{}