.NET Frustration - Process.GetProcessById返回新引用

Cha*_*had 3 .net equals long-running-processes

我正在编写将启动许多子进程的ac#程序.在稍后的某个时间,我需要通过ID检索这些进程,然后将这些进程与存储在Dictionary中的一组进程匹配,这些进程在首次创建时添加到Dictionary中.但是,我遇到了一个看似纯粹荒谬的问题......

Process notepad = new Process();
notepad.StartInfo.FileName = "notepad";
notepad.Start();

Process n2 = Process.GetProcessById(notepad.Id);

Debug.WriteLine(notepad == n2);       //'False', but Why isn't this true???
Debug.WriteLine(notepad.Id == n2.Id); //'True'
Run Code Online (Sandbox Code Playgroud)

我已经使用.NET Reflector来发现GetProcessById返回一个'new Process(...)',但它似乎应该找到对已经运行的进程的引用并返回它.

您可以假设第一个Debug语句本质上是一个调用

MyCustomDataType data = myDictionary [notepad];

我希望得到我最初插入的数据,而不是因为默认的比较器正在进行引用检查而得到KeyNotFoundException.为了解决这个问题,我在我的字典上添加了一个自定义IComparer,它只检查两个Process对象是否具有相同的ID,因此我可以按预期获得相关的数据.但是,这有其自身的问题,即未运行的进程没有进程ID,因此有时在我的自定义IComparer中调用Process.ID会引发InvalidOperationException!所以,我修复了一个问题只是为了创造另一个问题.

所以,我想我有两个问题:

  • 为什么.NET只返回对已经运行的Process实例的引用?
  • 我可以做什么来匹配存储在我的字典中的进程,因为使用进程ID并不总是在Process对象的生命周期内有效?

Fra*_*nov 5

不确定为什么你不得不求助于Reflector,因为GetProcessByIDMSDN文档明确指出:

创建新的Process组件,并将其与您指定的现有流程资源相关联.

框架无法返回您所拥有的相同实例.为了能够做到这一点,框架必须保持对所有已创建的Process实例的引用,并比较它们的进程ID以找出您已经拥有的那个.我将留给你想象一下这会对内存和框架的性能产生什么影响.

此外,Process类是OpenProcessWin32 API 返回的进程句柄的包装器.并且可以为同一个进程提供多个句柄.并且输入/输出重定向可以在每个句柄的基础上完成,因此,预期场景可以有两个表示同一进程的Process实例,其中一个处理输出和错误流,另一个处理输入流.

另外,在我看来,您正在使用Process对象本身作为Dictionary的键.但是Process对象并不代表实际进程的标识,它只是进程的一种表示.您应该使用代表流程身份的关键词.