Get rid of fallback to process ids enumeration in ProcessManager.IsProcessRunning (Windows) - #65041
Conversation
|
Tagging subscribers to this area: @dotnet/area-system-diagnostics-process Issue DetailsCurrently, when process Handle can't be opened for any reason (local machine case), I want to suggest some improvements to (mostly) get rid of this fallback to achieve better performance. Main suggestion is assume that process doesn't exists when But there are some special cases should be considered. Handle to process couldn't be opened:
In these cases we could (1 OR 2 OR 3):
What do you think, which way should be used? In this PR, I've implemented the first way, but it's not a problem to rewrite with second way if these optimistic assumptions are reasonable.
|
e1640f1 to
4965a88
Compare
adamsitnik
left a comment
There was a problem hiding this comment.
Hi @epeshk
Big thanks for your contribution and providing a very descriptive explanation. Please take a look at my comment and let me know what do you think about it.
Could you please say a little bit more about the scenario in which you are using this method and the optimization would help? Are you frequently calling Process.GetProcessById for pid that does not exist? If so, may I ask why? (I am trying to get a better understanding)
There was a problem hiding this comment.
The OpenProcess method can fail for multiple reasons. I am not 100% sure that all errors except ERROR_ACCESS_DENIED mean that the process does not exist. However, I think that it's safe to assume that when the method fails with ERROR_INVALID_PARAMETER the process does not exist and we can safely return false (I've tested it locally).
| if (error != Interop.Errors.ERROR_ACCESS_DENIED) | |
| return false; | |
| if (error == Interop.Errors.ERROR_INVALID_PARAMETER) | |
| { | |
| Debug.Assert(processId != 0, "OpenProcess fails with ERROR_INVALID_PARAMETER for Idle Process"); | |
| return false; | |
| } |
…rate processes on local machine only when handle check failed
4965a88 to
cce266a
Compare
Currently, when process Handle can't be opened for any reason (local machine case),
ProcessManager.IsProcessRunningenumerates all processes in the system to ensure that no process with given Id exists. This enumeration implemented viaEnumProcessescall which is very slow (~10ms) compared to good case when handle is successfully openedI want to suggest some improvements to (mostly) get rid of this fallback to achieve better performance.
Main suggestion is assume that process doesn't exists when
OpenProcessfailed not due to lack of permissions (ERROR_ACCESS_DENIED).But there are some special cases should be considered.
Handle to process couldn't be opened:
id=0) (ERROR_INVALID_PARAMETER)ERROR_ACCESS_DENIED)In these cases we could (1 OR 2 OR 3):
System.Diagnostics.ProcessManager.OpenProcessstill assumesERROR_ACCESS_DENIEDmeans still running process. So second way doesn't look completely wrong.What do you think, which way should be used? In this PR, I've implemented the first way, but it's not a problem to rewrite with second way if these optimistic assumptions are reasonable.