将IDisposable作为参数传递给方法并将其置于该方法中是一种好习惯。当你必须使用多个线程时,这是不可避免的。好吧,最佳实践说主人(来电者)应该处理它。
E.g。
public void MyMethod(MyClass reader){
using(reader){
//some code
}
}
如果所有者(创建线程)不再存在怎么办?例如。
interface IReader : IDisposable {
string Read();
}
public class MyReader : IReader {
public string Read()
{
return "hellow world";
}
public void Dispose()
{
//dispose code
}
}
在这里你会发现问题......
public void Start() {
MyReader[] readerSet = new MyReader[5];
for (int i = 0; i < readerSet.Length; i++) {
readerSet[i] = new MyReader();
}
foreach (IReader reader in readerSet) {
ThreadPool.QueueUserWorkItem(new WaitCallback(Run), reader);
}
//exit after creating threads
}
public void Run(Object objReader) {
IReader reader = (IReader)objReader;
using (reader) {
//use the reader
}
}
答案 0 :(得分:5)
我认为你最好带一个创作代表来保证对象的处理。
示例强>
public void Start() {
var makeReader = new Func<IReader>(() => new MyReader());
for (int i = 0; i < 5; i++) {
ThreadPool.QueueUserWorkItem(Run, makeReader);
}
}
public void Run(Object state) {
var makeReader = (Func<IReader>)state;
using (var reader = makeReader()) {
//use the reader
}
}
答案 1 :(得分:2)
不,主人应该处理它。所有者通常是首先创建IDisposable实例的对象。您可以阅读IDisposable最佳做法here。
传递性地处理您的类型中定义的任何一次性字段 来自你的Dispose方法。你应该在任何字段上调用Dispose() 其生命周期是您的对象控制的。例如,考虑一个案例 您的对象拥有私有TextReader字段的位置。在你的类型 Dispose,你应该调用TextReader对象的Dispose 反过来处理其一次性领域(Stream和Encoding,for 例子),等等。如果在Dispose内部实现(bool处理) 方法,这应该只在disposing参数是 在此期间不允许使用真实触摸的其他托管对象 定稿。 此外,如果您的对象不拥有给定的对象 一次性物品,不应该像其他物品那样试图处理它 代码仍然可以依赖它活跃。这两者都可能导致 微妙的检测错误。
最好尽量减少传递IDisposable实例,这样您就不必过多考虑所有者。
答案 2 :(得分:0)
这完全取决于您的具体情况。
一般来说,“所有者”应该处置该对象,但是你的工作就是找出那个对象。它可能不是创建者,也可能不是你的情况下的调用者。
答案 3 :(得分:0)
在从创建到Dispose调用的任何时刻,任何IDisposable实例都应该只有一个所有者负责删除它。通常,IDisposable的所有者将是创建它的实体,但是在某些情况下,让对象将IDisposable的所有权移交给另一个对象可能会有所帮助。例如,考虑以下两个假设类:
在许多情况下,加载SoundSource的例程在完成播放时并不会真正关心;让播放例程获得SoundSource的所有权更方便。请注意,在某些情况下,请求回放的例程可能希望保留SoundSource的所有权。最好的方法是允许例程的调用者指定是否希望保留或移交传入的IDisposable的所有权。