我对使用声明有疑问:
我有一个名为
的班级MyJob是一次性的。然后我在MyJob JobResults上也有一个属性,它也是Disposable。
我的代码:
using (MyJob job = new MyJob())
{
//do something.
FormatResults(job.JobResults)
}
public string FormatResuls(JobResuts results)
{
}
我的第一个问题是:在这种情况下,在使用块后,MyJob和MyJob.Results都被处理掉了或者只有MyJob而不是MyJob.Results?
我也在C#中执行w.r.t任务的并行处理:
Tasks allTasks = List<Tasks>
try
{
foreach(Task t in allTasks)
{
// Each tasks makes use of an IDisposable object.
t.Start();
}
Task.WaitAll(allTasks);
}
catch(AggregateExecption aex)
{
/// How do I ensure that all IDisposables are disposed properly if an exception happens in any of the tasks?
}
我的第二个问题,在上面的代码中,在处理任务中的异常时,确保正确处理对象的正确方法是什么?
很抱歉,如果我的问题太天真或令人困惑,因为我仍在努力学习和理解C#。 谢谢你们!
答案 0 :(得分:5)
既是MyJob又是MyJob.Results,或只是MyJob和NOT MyJob.Results?
这对于Dispose
方法的实施是主观的。由于我们在您的问题中没有看到它,我将假设您目前没有在Result
中处置您的MyJob.Dispose
属性,因此它将是后者。
由于只有MyJob
包含在using
语句中,并再次假设它对您的Result
属性不执行任何操作,因此它将被置于与Results
相对的位置,未包含在using
声明中。
您可以决定MyJob
,因为它封装了您的Result
属性,也负责一次性使用它。如果您这样做,可以在Results
中处理MyJobs.Dispose
。
什么是确保在正确处理对象时的正确方法 处理任务中的异常?
如果传递给Task
的委托包含在using
语句中,那么您是安全的,因为using
会将您的代码转换为try-finally
块,如果using
阻止发生异常,则finally
阻止仍会运行yourObject.Dispose
。
答案 1 :(得分:2)
只处理MyJobs。对于其他属性,您需要了解对象所有权:拥有该对象的人应负责(通常)处置它。实现IDisposable的属性可以被其他实例使用,因此如果您是创建它的人并且没有其他引用,则只能处置它,或者如果知道它已经被处理掉,则该类会正常失败。 / p>
答案 2 :(得分:2)
这里有很多好的答案,但还有一件事。如果你想确保你的对象被正确处理,因为它使用了非托管资源,你应该在你的对象中实现一个析构函数,如:
class MyJob : IDisposable
{
private bool _disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
//Dispose unmanaged resources and any child disposables here
}
}
void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
~MyJob()
{
//ONLY use if you have unmanaged resources that DO NOT
//implement their own finalizers.
Dispose();
}
}
但是,建议您不要使用终结器(析构函数),除非您要使用不包含自己的终结器的非托管资源最终确定类型。
有关实施IDisposable的最佳做法,请参阅https://msdn.microsoft.com/en-us/library/b1yfkh5e.aspx。
答案 3 :(得分:0)
1)最好的方法是在MyJob的Dispose()方法中部署JobResults
。否则它不会自行处理
2)我会实现finally
部分,遍历每个对象并进行处理。但在大多数情况下,你不需要这样做read this