19

Simple question: I want to open a URL using the Default Browser, so I just do Process.Start(url). However, I noticed that this returns an IDisposable object.

So now I wonder if I have to dispose it? Or, for that matter, if my Application is in any way responsible for this process? The intended functionality is simply "Fire and forget", I do not want to have my application as a parent of the new process and it does not need to interact with it.

I've seen some similar but unrelated questions on SO that seem to say that simply calling Process.Start on a URL is fine, but I do not want to run into some hard to debug memory leaks/resource exhaustion issues caused my me program keeping references to long dead browser processes.

Michael Stum
  • 177,530
  • 117
  • 400
  • 535

4 Answers4

12

No, you do not.

void Main()
{
    Process result = Process.Start("http://www.google.com");

    if (result == null)
    {
        Console.WriteLine("It returned null");
    }
}

Prints

It returned null

From Process.Start Method (String) on MSDN (.NET Framework 4):

If the address of the executable file to start is a URL, the process is not started and null is returned.

(In general, though, the using statement is the right way to work with IDisposable objects. Except for WCF clients.)

Community
  • 1
  • 1
TrueWill
  • 25,132
  • 10
  • 101
  • 150
  • Even when the browser process **IS** started, it still returns null! – AgentFire Jun 09 '15 at 17:15
  • @AgentFire You'll always get null for a URL, whether or not your browser has to load. That's the point - you don't have to dispose in this specific case (URLs). – TrueWill Jun 11 '15 at 20:40
11

Couldn't you just wrap it in a using clause to ensure the GC does whatever it needs to do with it IF you are required to dispose of it? This would still allow a sort of "fire and forget" but not leave memory/resources in a bad state.

Probably overkill but there is a really good article on CodeProject about the IDisposable interface: http://www.codeproject.com/KB/dotnet/idisposable.aspx

Sam Harwell
  • 97,721
  • 20
  • 209
  • 280
Fooberichu
  • 428
  • 1
  • 5
  • 13
  • The problem is that I do not fully understand the object life in this situation. If I do using(Process.Start(url)); then will it wait at that point? Or will it dispose the process to early? At the moment, that makes no difference in behavior so I _guess_ that there are no resources that are kept open, but I don't know for sure and i do not know how to measure that. – Michael Stum Aug 06 '09 at 20:34
  • Since the "using" clause implicitly instructs the compiler to build a try/finally and implement a dispose and the fact that they are returning an IDisposable object I think you'd be safe to do that. By not deallocating it you may be tying resources up. You could try building a loop that opens several URLs without disposing them and see if your resources balloon out of control and another test by wrapping them in using clauses. The caveat is you'll have a bunch of windows to close after that. :) – Fooberichu Aug 06 '09 at 20:49
7

Starting the process is a native call which returns a native process handle, which is stored in the instance of Process that is returned. There are methods in Process that use the handle so you can do things like wait for the process to exit, or become idle.

Disposing the Process frees that handle. I agree with Jon, wrap it in a using clause.

Matt
  • 2,984
  • 1
  • 24
  • 31
3

@Fooberichu's answer is spot on, but I think it's also worth pointing out that usually only a few things "need" to be explicitly disposed.

Objects are always effectively disposed at some point:

  • Any time the GC does a collection, it will (eventually) dispose of objects that are no longer referenced. So if you don't manually dispose, the object may still be disposed within a few seconds of it going out of scope.
  • When your application quits, all resources it held are released. (Although the objects may not be disposed by C#/.net, the OS will claim back pretty much anything your process grabbed. If the lifetime of the resource extends beyond your application, then the OS is usually responsible for cleaning it up)

The point of manually disposing (or employing a 'using') is therefore not to ensure that the resources will be released, but to release them as early as possible.

These days you are unlikely to run out of most types of resources (e.g. memory, file handles, or system brushes). However, if you hold on to resources when you don't need to, your program is likely to be less efficient, you might use more memory than necessary, or perhaps cause delays by temporarily blocking other applications from doing useful things, etc. In general, then, Disposing is about good etiquette, tidiness and cutting out unnecessary inefficiencies.

There are a few cases where resources must be released (e.g. if you don't close a file, you can't open/rename/move/delete it from elsewhere in your program or other programs; if you keep allocating textures on your graphics card without releasing them, you'll run out of VRAM and the computer's display will fail), but in general, you will encounter these situations infrequently, and if you follow best practices (explicitly disposing objects when they're no longer needed), you won't usually need to know when these situations are occurring because you'll already be dealing with them correctly.

Jason Williams
  • 56,972
  • 11
  • 108
  • 137
  • 2
    In many cases IDisposable classes do not have finalizers. If they are GC'd without being **explicitly** disposed, any unmanaged resources associated with them will be leaked. The framework classes do a good job of protecting us in most cases, but the best practice is to always dispose of IDisposable objects. This and WCF clients happen to be two weird edge cases. – TrueWill Oct 11 '13 at 17:44
  • `Any time the GC does a collection, it will (eventually) dispose of objects that are no longer referenced. So if you don't manually dispose, the object may still be disposed within a few seconds of it going out of scope.` This is no way guaranteed. The finalizer does not guarantee to call `Dispose`. It will eventually _garbage collect_ yes (well, technically "probably") - but not necessarily `Dispose`. – mjwills Dec 22 '20 at 04:35