它最近向我指出,各种LINQ的扩展方法(如Where,Select等)返回IEnumerable<T>,恰巧也有IDisposable.以下评估结果True
new int[2] {0,1}.Select(x => x*2) is IDisposable
Run Code Online (Sandbox Code Playgroud)
我是否需要处理Where表达式的结果?
每当我打电话给一个方法返回时IEnumerable<T>,我(可能)接受在我完成它时调用dispose的责任吗?
不知道是否有更好的方法来做到这一点,所以这就是问题的原因.我可以使用以下代码检查特定计算机上是否存在服务:
bool DoesServiceExist(string serviceName, string machineName)
{
ServiceController controller = null;
try
{
controller = new ServiceController(serviceName, machineName);
controller.Status;
return true;
}
catch(InvalidOperationException)
{
return false;
}
finally
{
if (controller != null)
{
controller.Dispose();
}
}
}
Run Code Online (Sandbox Code Playgroud)
但这对我来说似乎是一个无效的解决方案(由于异常处理).有没有更好的方法来检查服务是否存在.注意 - 我最近切换到.Net 4.0,所以如果有人知道4.0中更好的解决方案是可以接受的.
编辑:这是一个示例c#控制台应用程序,用于测试我的示例以及GetServices代码示例的性能.在我的测试中,我发现GetServices在服务不存在的情况下表现更好,但是当服务存在时速度慢两倍:
static void Main(string[] args)
{
string serviceName = string.Empty;
string machineName = string.Empty;
var sw = new Stopwatch();
sw.Reset();
sw.Start();
for (int i = 0; i < 1000; i++)
{
ServiceExistsException(serviceName, machineName);
}
sw.Stop();
Console.WriteLine("Elapsed time: " …Run Code Online (Sandbox Code Playgroud) 我的理解是,LINQ IEnumerable扩展应该在IEnumerable产生的IEnumerator上调用Dispose。在SO上看到这个答案。但是,我在实践中没有看到。其他答案是否正确,还是我在LINQ中发现错误?
这是使用Mono发行的发行品的最低限度的复制。它还在Dotnet Core 2.1和2.2中进行了复制。
using System;
using System.Threading;
using System.Linq;
using System.Collections.Generic;
using System.Collections;
namespace union
{
class MyEnumerable : IEnumerable<long>
{
public IEnumerator<long> GetEnumerator()
{
return new MyEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
class MyEnumerator : IEnumerator<long>
{
public long Current
{
get
{
return 0;
}
}
object IEnumerator.Current
{
get
{
return Current;
}
}
public bool MoveNext()
{
return false;
}
public void Reset()
{
return; …Run Code Online (Sandbox Code Playgroud)