Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 处理未使用的IDisposable返回值是否重要?_C#_.net_Return Value_Dispose_Idisposable - Fatal编程技术网

C# 处理未使用的IDisposable返回值是否重要?

C# 处理未使用的IDisposable返回值是否重要?,c#,.net,return-value,dispose,idisposable,C#,.net,Return Value,Dispose,Idisposable,有一些静态方法,例如Process.Start()和File.Create(),它们构造并返回通常被丢弃的IDisposable实例。使用这些方法很正常,好像它们返回void,如果你不注意,你可能会忽略它们甚至有返回值的事实 我知道总是处理IDisposable实例是一种很好的做法。这是否适用于未使用的返回值?而不是编写Process.Start(processPath)您是否应该始终编写Process.Start(processPath.Dispose() 我想这显然是肯定的,但我不得不自己再

有一些静态方法,例如
Process.Start()
File.Create()
,它们构造并返回通常被丢弃的
IDisposable
实例。使用这些方法很正常,好像它们返回
void
,如果你不注意,你可能会忽略它们甚至有返回值的事实

我知道总是处理
IDisposable
实例是一种很好的做法。这是否适用于未使用的返回值?而不是编写
Process.Start(processPath)
您是否应该始终编写
Process.Start(processPath.Dispose()


我想这显然是肯定的,但我不得不自己再猜一猜,因为我只看到在没有
Dispose()
的情况下完成它。C#是否有一些自动处理这些情况的方法?

在大多数情况下,处理
IDisposable
实例的首选方法是使用
使用
语句:

using (var file = File.Create())
{
   //use file instance
}

这个语法糖将确保在您使用语句块退出
后显式地释放文件实例。实际上,它将您的代码包装到try/finally块中。

.NET有Finalizer的概念和许多实现IDisposable的BCL类型,也实现Finalizer。您可以查看文章并发布更多详细信息。因此,如果您不手动处理某些对象,它可能会在以后被处理。问题是以后(以及其他潜在的问题)是否适合您,或者您需要在某个特定点明确地、决定性地处理它

跳过Dispose方法调用和依赖终结器的缺点在线程中进行了描述,包括:

  • 性能问题
  • 使用时间比预期长的锁定资源的问题
  • 即使您有异常处理策略,也存在崩溃风险
  • 一般来说,我强烈建议始终显式调用Dispose方法,以避免出现奇怪的问题


    但是,您应该只处理您拥有的对象(您创建并知道它们何时不再使用)。当我使用某个IDisposable资源,获取另一个IDisposable作为它的属性时,我遇到过这样的情况,很明显,在我停止使用引用对象之前,我不应该处理对象的属性-当处理对象时,它将自己处理它。

    所有常见的注意事项也适用于此,这些情况都不是例外。是的,有一种自动处理的方法:如果一个类本身封装了非托管资源(比如说,一个进程句柄),它将有一个终结器,在垃圾收集器到达时负责释放这些资源。显然,这不如你一做完就把东西处理掉。您经常看到人们变得马虎的原因是因为代码是一次性的,或者它在退出之前不会创建多个进程或文件。在这种情况下,您没有尽快处理的事实不会被注意到。对象是由您所做的调用返回还是由您编写的代码初始化是无关紧要的。重要的是不清理资源的后果。您不应该使用
    Process.Start(processPath).Dispose()
    而是
    使用(var p=Process.Start(processPath)){}
    Start
    可能会抛出异常,在这种情况下,后一种方法将确保它无论如何都被释放。@TimSchmelter
    Process.Start(..).Dispose()
    与在泄漏句柄等方面使用
    没有什么不同。如果Start抛出异常-在Start函数外部没有任何可处理的内容。但不要使用
    HttpClient
    执行此操作,而是创建一个应用程序范围的静态实例:D@john是的,你是对的,然而,这是另一个话题,因为HttpClient本身存在一些潜在的架构缺陷:)这个答案并没有完全反映我的问题。您所说的情况是,将返回值分配给一个变量,然后使用它。我说的是返回值未使用的情况。在这种情况下,using块将是空的。这让我觉得太尴尬了,不能称之为语法糖。@KyleDelaney我同意,我必须更精确,最终,首选的方式意味着,不管是什么特定的用例,创建的实例都应该被处理:)我理解使用
    Dispose()
    有一些微妙的优势,但是空块看起来像是一个错误,因此我仍然可以使用
    Dispose()
    ,以提高可读性。