因此,当我关闭表单时,我正在处理许多对象。即使它可能会自动处理它。但我仍然倾向于遵循处理中的“规则”,希望它会坚持并帮助防止错误。
所以这就是我目前处理的方式,它有效。
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();
}
所以基本上,首先是如果一个博尔是真的,这意味着如果它不是那些可以忽略的,因为我认为它们并没有被制作出来。
如果有的话,其他的只是让我处理的方法。但这不是一个很好的方式,我想把它放在一个大功能中,意思是。
如果不处理则处理。或者其他的东西。 我知道他们中的许多人都有“被处置”的布尔,所以如果我可以检查每个对象,并且如果它是假的则应该可以处理。
答案 0 :(得分: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);
如果您想避免将其称为明确,请将它们全部存储在List<>
:
private List<IDisposable> _disposables;
void DisposeAll() {
foreach(IDisposable id in _disposables) {
if(id != null) id.Dispose();
}
}
答案 1 :(得分: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();
}
}
答案 2 :(得分:1)
我建议您使用using statement。因此,使用您的代码,它看起来像这样:
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的范围更加清晰。
答案 3 :(得分:1)
我认为你要解决的唯一问题是如何以更好的方式编写以下内容:
if (Wasout != null)
Wasout.Dispose();
if (SendStream != null)
SendStream.Dispose();
using
关键字已经实现了很多逻辑。在为您致电Dispose()
之前using
checks that the variable is not null。此外,using
保证抛出的异常(per {Wasout.Dispose()
)不会中断在其他列出的对象(例如Dispose()
)上调用SendStream
的尝试。似乎using
旨在允许基于范围规则管理资源:使用using
作为写o.Dispose()
的替代方式可能被视为滥用该语言。但是,using
行为的好处和它所带来的简洁性非常有价值。因此,我建议将“if (o != null) o.Dispose()
”的大量静态编写批次替换为“空”using
:
using (
IDisposable _Wasout = Wasout,
_SendStream = SendStream)
{}
请注意,调用Dispose()
的顺序与using
块中列出对象的方式相反。这遵循以与实例化顺序相反的方式清理对象的模式。 (想法是稍后实例化的对象可能会引用先前实例化的对象。例如,如果您使用梯子攀爬房屋,您可能需要保持梯子,以便您可以在之前爬回放弃它 - 梯子首先被实例化并最后清理。嗯,类比......但是,基本上,上面是shorthand for nested using
。不同的对象可以被砸到同一个using
块用using
来表示IDisposable
。