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)
{}