Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Process should have a TryGetProcessById method #27411

Closed
mnmr opened this issue Sep 17, 2018 · 10 comments
Closed

Process should have a TryGetProcessById method #27411

mnmr opened this issue Sep 17, 2018 · 10 comments

Comments

@mnmr
Copy link

mnmr commented Sep 17, 2018

Process currently only provides GetProcessById, which throws an exception instead of returning null when no such process exists. The only alternative to this is to enumerate all processes, but this can take a while and is for our use case completely unnecessary.

It would be really nice if there was a TryGetProcessById method to attempt to find the process without triggering an exception.

@danmoseley
Copy link
Member

Hello, we have some threshold of usefulness that we try to meet before adding a TryXXX variant of an API - otherwise (1) there would be thousands of them and (2) there is a concern that it turns .NET code into a return code world, which is less consistent and arguably less debuggable (see: HRESULT).

Generally we add these when exceptions tend to have a measurable perf impact - eg., that is why we have TryParseXXX, because parsers are perf sensitive and often cannot predict exactly the data. Or possibly it is causing significant debuggability issues.

There is some discussion of this in https://github.com/dotnet/corefx/issues/19928 (which should probably get restarted)

Having said that -- what is your motivation in this case?

@mnmr
Copy link
Author

mnmr commented Sep 18, 2018

Ah, I can see you’ve been discussing the topic for a while.

My motivation is academic, in the sense that I am strongly opposed to using exceptions for anything that is not exceptional, and practical, because I want to handle common failures without adding lots of code.

Asking for a process without knowing whether it exists is in my book similar to parsing a string and not knowing whether it’s a number: it may succeed or fail, with neither case being exceptional.

I would support the inclusion of any Try* method (or alternative overload) that provided access to framework logic without throwing. The try pattern is nice because it allows you to conditionally operate on the result in a concise manner, unlike try-catch which adds a lot of boiler-plate code and consumes much vertical space. I think the bar for adding these should be very low :-)

@danmoseley
Copy link
Member

I'd like to take this and several of the others mentioned in the other issue back to API review at some point. As noted in the other issue it ought to be possible to eg start VS without so many exceptions.

@krwq
Copy link
Member

krwq commented Sep 18, 2018

I'd like to understand when is this scenario useful - if you've used .NET to create a process you should have a Process instance and be able already able to check if process is finished, if you don't then it is pretty rare case than ID you got from somewhere else is invalid.

You can always wrap the call in try ... catch if you need it and if this is needed for perf then I'd like to understand what is the scenario when this is needed to be done faster - the only thing I can think of is guessing PIDs but that doesn't seem like something we'd add API for.

I like the functional approach but I guess you could just create something like:

        static T NonThrowing<T>(Func<T> f) where T : class
        {
            try
            {
                return f();
            }
            catch
            {
                return null;
            }
        }

and then use it as NonThrowing(() => Process.GetProcessById(123))

@mnmr
Copy link
Author

mnmr commented Sep 18, 2018

We use the Actor programming model, and the actor creating the process is not the same as the one monitoring whether it has exited unexpectedly (and Process is not serializable).

It’s not that there aren’t workarounds - static helpers, extensions, etc. It’s just cumbersome that you have to do this in the first place.

It’s incomprehensible to me that it is not desirable to always be able to avoid exceptions. Just a simple case such as this results in exceptions being used for control flow - if success return thing else return null. Expressions such as those should not require use of try catch.

@krwq
Copy link
Member

krwq commented Sep 18, 2018

@mnmr - I have mixed feelings on this subject - on one hand I agree that non-throwing model is almost always (at least for me) more convenient but on the other hand when you expect something will return a result but it returns null then it is exception which is useful as it will usually contain the message why something failed - if you provide only non-throwing options then debugging that is quite annoying (especially when you got limited access to the machine). It really all depends on what your expectations are and how you write a code.

In .NET a long time ago we made a decision than in most of the cases we will throw - while I prefer no exceptions I still value consistency across APIs rather than my own preference. If we find that a lot of people prefer it this way we will likely add matching API - so far this is the first request.

For things like this I usually just write tiny wrapper which does what I mean and move on - I do not think there is or ever will be one solution suits all when it comes to coding style or syntax.

@mnmr
Copy link
Author

mnmr commented Sep 19, 2018

I agree with all of that really, but do not think that adding try methods pollutes the framework - instead they bring freedom of choice, so developers can choose whatever fits their needs.

Overall it’s not a big deal either way, but at least now my vote is registered :)

@jnm2
Copy link
Contributor

jnm2 commented Sep 20, 2018

Re: NonThrowing helper, keep in mind that Try* is not the same as catch-all. Try* should return false for tightly-defined straightforward criteria and still throw for exceptional circumstances. For example, ArgumentException, or an IOException when TryParsing a stream that happens to be backed by the file system.

@mnmr
Copy link
Author

mnmr commented Sep 25, 2018

@jnm2 Absolutely, but that’s also the intended purpose of exceptions.

I just strongly believe it to be an anti-pattern when you’re relying on exceptions to convey information that could be returned directly, in one way or another.

@msftgits msftgits transferred this issue from dotnet/corefx Jan 31, 2020
@msftgits msftgits added this to the Future milestone Jan 31, 2020
@maryamariyan maryamariyan added the untriaged New issue has not been triaged by the area owner label Feb 23, 2020
@adamsitnik adamsitnik removed the untriaged New issue has not been triaged by the area owner label Jul 6, 2020
@jkotas
Copy link
Member

jkotas commented Apr 27, 2024

Duplicate of #101582 that is formatted as proper API proposal.

@jkotas jkotas closed this as completed Apr 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants