I am studying asynchronous C# Sockets at the moment and i have noticed something that i am confused about.
In all the End...(Accept/Connect) etc there is a code section like:
Socket s = (Socket) ar.AsyncState;
Here it is being casted as a socket.
As each End uses these local Sockets is there any point in trying to close() any of them once I am done?
What is the best practice?
Most authors seem to agree that if something implements IDisposable, you should call Dispose. The easiest way to do this is to use 'using' which automatically calls Dispose for you.
using (DirectoryEntry de = new DirectoryEntry(path))
{
.... some code
}
I think the best practice for sockets is similar to that for the streams. I personally always use the close() methods in both - sockets and streams. If something has been opened, it should be properly closed :)
It will get closed eventually even if you don't (when the garbage collector kicks in), however best practices dictates that you close handles to objects when you no longer need them.
Consider file streams, not closing a file stream can mean that data will not be wrote to a file. Sutble problems like this can occur if you do not explicity close the handle of objects that should be closed.
Closing your sockets is critical. Just because you don't notice any ill effects in a particular Framework version doesn't mean in future implementation the Framework might leave resources in use until it is closed. You most likely are leaving resources in use on the system as well. Plus, it doesn't hurt. :p
The object probably does free its resources and implictly close the socket when it is destroyed, but with a automatic garbage collected environment like C#, you never know when that might happen.
Either by using the
using(Socket s)
{
...
}
or by using socket open and at the end closing the socket.
If you leave a socket opened and try to open it again somewhere else then a runtime error will occur...
All streams dataReaders, connections must be closed.
the main reasons seem to be:
1. security
2. waste of memory
3. prone to runtime errors
I suggest either Disposing or Closing the stream after you are done. This allows the system to immediately free the network resources once you are done with your socket.
If you are using the socket from a single function, the using statement works well as it implicitly disposes your object. Otherwise (for example when keeping a socket active, maintaining a reference to it in an object), you will want to either call Close() or Dispose() when you are done. Otherwise, the socket could stay open indefinitely. Dispose() may be a slightly better choice because it frees more resources than a Close() would.
MSDN may skip the Close because the socket will be automatically closed at the termination of the process when the remaining resources are garbage collected.
Socket.Close calls Dispose. Calling Dispose, either explicitly or implicitly, on an IDisposable object is obligatory. The IDisposable interface is for objects that use unmanaged resources, so allowing the object to be garbage collected without calling dispose will result in resource leaks. A short sample program may not show this problem, but a full, long running problem will certainly run into problems.
Related
It has come to my attention that certain resources should be disposed of after utilizing them or closed etc;
Is there a rule of thumb as to what exactly should be closed / disposed?
Example - when you use StreamWriter , you want to close that when you are done to avoid errors etc. What are things that should absolutely be closed / disposed of and when?
The rule of thumb is... (drumroll, curtains pull back, pyrotechnics go up, and as the smoke clears)
Every time you are done using an object, if and only if the type1 implements System.IDisposable
Oh, you were expecting something complicated? Sorry to disappoint.
1The concrete type of the object. Sometimes that needs a runtime check, e.g. with IEnumerator implementations.
As #BenVoigt says, you should dispose of an IDisposable if you are done using that resource. C# introduced the using keyword for developers ease of use:
Example:
using (FileStream SourceStream = File.Open("file.ext", FileMode.Open)) {
//do something with the file
}
This keyword is a syntactical way to ensure that you dispose of your resource once you exit a method, etc. Of course some resources can be shared over multiple methods, threads, etc. so this language construct is not always available.
In many cases however, it's not that bad to forget to dispose of such object. If the program does no longer refers to it, the garbage collector will eventually walk by and dispose of it itself. Disposing of objects is however useful if the resource is large (a large file) or uses network resources (e.g.: a database connection). Since it releases resources that can be reused by other programs/users/clients/...
Furthermore disposing of objects is useful if they can be shared over multiple processes, threads, etc. like for instance files.: say you write to a file, then other programs need to wait until the write process has ended. If however program A waits for a file in use by process B and vice versa, a deadlock will occur: both programs wait for each other but don't give up their own resource. By disposing of such resources as soon as possible, most deadlocks will be prevented.
When you call Close on an active StreamWriter it makes it impossible to write any more code to the stream (since it's been closed). To open another stream, you have to make a new instance of a StreamWriter since there's no 'Open' method.
My question is, what's the point in having Close and Dispose when you can't really use anything besides Dispose after closing the stream?
I could understand if there was an Open function, i.e. you could close one file then open another using the same StreamWriter. But as there is only Close and you can't really use anything besides Dispose afterwards, why not just get rid of Close and have Dispose close the underlying stream as its first action?
I get that Dispose comes from IDisposeable and all that. What I want to know is why Close is needed specifically when Dispose appears to call Close anyway.
As far as I can see, without the ability to open another stream with the same StreamWriter, there is no point in having Close when you have no option but to Dispose afterwards since all other methods become useless.
Why is is that StreamWriter bothers having Close when they could merge Close and Dispose into a single method?
When dealing with streams there's a long standing convention that Close is a method that they have to close the stream. It's terminology that many programmers are used to and expect to see when dealing with streams. It would have been potentially confusing to have a stream without a Close method, and may have taken some time for people to realize that they should use Dispose to close the stream.
It's certainly possible for the class to have implemented IDisposable explicitly, so that the Dispose method wouldn't be there without a cast to IDisposable, and that my have cleaned up some of the confusion, but they choose not to do that and to leave two duplicate methods in the class.
It's entirely up to your personal preference whether you use Dispose or Close to close the stream.
According to the documentation, Close just calls Dispose with a value of true.
This method overrides Close.
This implementation of Close calls the
Dispose method passing a true value.
You must call Close to ensure
that all data is correctly written out to the underlying stream.
Following a call to Close, any operations on the StreamWriter might
raise exceptions. If there is insufficient space on the disk, calling
Close will raise an exception.
Dispose itself is inherited from IDisposable, which is used by classes that have resources that need to be released.
Opening a stream allocates both application and system resources. If your application opens many streams without closing them, then it restricts the ability of other applications to access those files. It's important that streams are closed as soon as possible.
As far as why streams don't have the ability to reopen, this is basically the .NET approach. The class represents an open stream. So create one to access the stream and get rid of it as soon as possible. When you want to access the stream again, you create another one.
I think it would be valid to create a stream class that could be reopened, but it does cause some problems as many of the methods wouldn't work when the stream was closed. In the end, a stream class really does represent an open stream.
Dispose is just there to make it easier to ensure the stream gets cleaned up in a timely manner.
why not just get rid of close and have dispose close the underlying stream as its first action?
It's good programming practice.
Suppose you have lights in your house that turn off automatically when you leave. You wouldn't have to turn off the lights when you left, but it's good practice. That way, you wouldn't require that every house you live in to automatically turn off the lights. You'd be in the habit of turning them off yourself.
Explicitly calling Close() tells the reader (and the system) "I'm done with this stream", and calling Dispose() tells the system (and the reader) "you can release any embedded resources".
You are on the right track when you say "why not just get rid of..." except it's backwards. If you look at the underlying code for StreamWriter.Close() you will see:
public override void Close()
{
this.Dispose(true);
GC.SuppressFinalize((object) this);
}
So the Close() method is just the way you would tell the framework that you are done writing to the stream.
I'm making a program which sends data to many TCP listeners. If one of the TCP Sending channel is no more used, do we need to close it using TCPClient.close. What happens if we leave it open?
Thanks!
I wouldn't use Close explicitly - I'd just dispose it via a using statement:
using (TcpClient client = ...)
{
// Use the client
}
What happens if we leave it open?
If neither side closes the connection, it'll be sitting there doing nothing, pointlessly.
If the other end closes the connection, I suspect you'll have a local connection in TIME_WAIT or something similar for a while; I don't know the exact details but it's not ideal.
The main point is that it may use up some system resources, and fundamentally it's not ideal. Is it going to cause your program to crash and your system to go crazy? Probably not - at least unless you're creating a huge number of these. It's still a good idea to dispose of anything with non-memory resources though.
If you leave it open, the GC (Garbage Collector) will in time dispose of your object.
With TCPClient, the finalizer (the code run when the GC cleans up your object) has a call to Dispose(), which in turn closes the connection and frees any OS resources used by it.
You don't know WHEN the GC does it's cleaning up, so this approach is undeterministic. This probably isn't a problem with one or two open connections, but you may starve the system of resources if you open a huge number of these.
A good practice would be to always dispose TCPClients when you're done with them, and this can easily be accomplished with the using block. (As shown in Jon Skeets answer...)
Do I have to use a using statement to dispose immediately even in a method? Or will the ending of the method cause an automatic Dispose of all local variables including graphics?
(I’m asking this because I’ve seen examples that have Dispose calls at the end of methods, and wanted to know if that’s really necessary.)
Thanks.
Yes, you do. Going out of scope does not do anything; it does not call Dispose(), it does not garbage-collect, it does not call a finalizer.
If the type is IDisposable, then yes. It is your job to tidy up after yourself (assuming that the object is actually "done with" at this point).
Possible side-effects of not doing this:
files get left open and cause access-exceptions (FileStream)
connections get left open and cause pool saturation (DbConnection)
unmanaged handles get saturated and cause resource starvation (any winforms/etc)
transactions get left open and cause blocking (TransactionScope / DbTransaction)
etc
basically, bad things.
Furthermore, in most cases where you see Dispose() at the bottom of the method, a using would be preferable. There are some cases where that isn't possible (fields on an object, for example), but the point remains: it sounds like those are bad examples.
You don't ever have to dispose of an object. But if you want to release unmanaged resources earlier rather than whenever the GC gets around to it (which is when it processes the fReachable queue) then yes you should since the scope of of a method does not determine when a disposable object's finalize will be called.
For more you might want to read Jeffrey Richter's Garbage Collection: Automatic Memory Management in the Microsoft .NET Framework
As delnan noted if there's a hard limit to the resources you're using you're much more likely to impacted if you let it get reclaimed by the GC rather than calling Dispose. DB connections are a good example of this kind of reasource and is certainly the reason why the NumberOfReclaimedConnections performance counter got created.
Yes, use using. It is a great statement.
Actually if you don't call Dispose (either manually or by using using), you can end up in a situation where your managed memory is stil quite empty, but unmanaged resources are depleted. Eventually it can cause a deadlock because other objects or other processes will wait for your unmanaged resources and you will wait for them. (Garbage collector won't run, because managed memory still won't be full.)
So please call Dispose as soon as you can. Once you don't need an object which has got that method defined, call it.
Certainly we should call Dispose() on IDisposable objects as soon as we don't need them (which is often merely the scope of a "using" statement). If we don't take that precaution then bad things, from subtle to show-stopping, might happen.
But what about "the last moment" before process termination? If your IDisposables have not been explicitly disposed by that point in time, isn't it true that it no longer matters? I ask because unmanaged resources, beneath the CLR, are represented by kernel objects - and the win32 process termination will free all unmanaged resources / kernel objects anyway. Said differently, no resources will remain "leaked" after the process terminates (regardless if Dispose() was called on lingering IDisposables).
Can anyone think of a case where process termination would still leave a leaked resource, simply because Dispose() was not explicitly called on one or more IDisposables?
Please do not misunderstand this question: I am not trying to justify ignoring IDisposables. The question is just technical-theoretical.
EDIT: And what about mono running on Linux? Is process termination there just as "reliable" at cleaning up unmanaged "leaks?"
LATE EDIT: Although "other uses" may exist for IDisposables, my focus is strictly on resource leaks. I've heard two answers: (1) if your process refuses to terminate, you will have a leak and (2) yes, resources can leak even if the process terminates. I certainly agree with item (1), though it is just outside the scope of what I'm after. Otherwise, item (2) is exactly what i'm looking for, but I can't shake the feeling it is just a guess. Jeffrey Richter ("Windows via C/C++") explains that a (gracefully) terminated Win32 process will not leave leaked or orphaned resources. Why would a process containing the CLR change that? Where is the documentation, specific example, or theoretical scenario that gives credance to the idea that the Win32 process cleanup capability is compromised when using the CLR?
Technically speaking, it all depends on what the IDisposable does. It has been used for a lot of things, not just unmanaged resources.
For example, when working on an Outlook application I had built a nice little abstraction of the Outlook API. Attachments were particularly annoying to work with as streams because you needed to save it out to a temp file, work with it, then clean it up.
So my abstraction looked something like this:
OutlookMailItem mailItem = blah;
using (Stream attachmentStream = mailItem.OpenAttachment("something.txt")) {
// work with stream
}
When Dispose was called on the AttachmentStream, the temp file it was based on was deleted. In this case, if Dispose was not called, the temp file would never be cleaned up. I had a process at startup to look for these orphaned files but I figured I'd present this as an example.
In reality, nearly all IDisposable implementations which wrap some kind of socket, handle, or transaction will simply be cleaned up by the operating system upon process termination. But obviously that's like welfare. Avoid it if you can.
During a cooperative shutdown, the AppDomain is unloaded, which causes all finalizers to execute:
From Object.Finalize documentation:
During shutdown of an application domain, Finalize is automatically called on objects that are not exempt from finalization, even those that are still accessible.
So you're safe on shutdown as long as two criteria are met:
Every IDisposable object that's still alive has a correctly-implemented finalizer (true of Framework classes, may not be true of less-trustworthy libraries); and
It's actually a cooperative shutdown, and not an abnormal shutdown such as a hard process termination, Ctrl-C in a console app, or Environment.FailFast.
If either of these two criteria aren't met, it is possible that your application is holding onto global unmanaged resources (such as a mutex), which actually will leak. Therefore, it's always better to call Dispose early if you can. Most of the time, you can rely on the CLR and object finalizers to do this work for you, but better to be safe than sorry.
One thing that I often find myself disposing is serial ports-- now, while a serial port should be freed when the program lets up, other programs can't access the serial port while it's being held by another process. So, if your process refuses to die, then you're tying up a serial port. That can be really bad if the user tries to restart your program, but a zombie version of the previous process is still holding on to the serial port.
And yes, I've had my program find itself in a zombie state before, and then the customer complain that the program isn't working anymore because the program fails to attach to the serial port on restart. The result is either walking the user through killing a process in the task manager or having them reboot, neither of which is a particularly user-friendly task.
You write your custom code to free objects in your disposable class. It's for you to write code to free unmanaged and managed code.
This is why we need Dispose function. All freeing up of memory is not automatic, like you said in unmanaged code's case.
Now, if you think that unmanaged code is automatically freed by OS, it's not true. There are many handles and locks that may remain active if not properly disposed by your application.
First, I would like to point out that IDisposable is not only for Windows kernel objects or unmanaged memory. Rather, it is for things that the garbage collection does not understand (of which kernel objects are a special case).
A small example, just to give you an idea:
sealed class Logger : IDisposable
{
private bool _disposed = false;
public Logger()
{
System.IO.File.AppendAllText( #"C:\mylog.txt", "LOG STARTED" );
}
~Logger()
{
Dispose();
}
public void Dispose()
{
if ( !_disposed )
{
System.IO.File.AppendAllText( #"C:\mylog.txt", "LOG STOPPED" );
_disposed = true;
}
}
public void WriteMessage( string msg )
{
System.IO.File.AppendAllText( #"C:\mylog.txt", "MESSAGE: " + msg );
}
}
Note that this Logger class does not "hold" any kernel-object-style resources. It opens file and closes it right away. However, there is this logic behind that it should write "LOG STOPPED" when the object is destroyed. This logic is something that GC cannot understand - and this is the place to use IDisposable.
Therefore, you cannot count on Windows cleaning up kernel objects after you. There might still be something even Windows doesn't know.
That being said, however, provided your disposable objects are properly written (i.e. calling Dispose in finalizer), they will still be disposed by the CLR upon process exit.
So, the answer is: yes, it is not necessary to call Dispose just before project exit. But NOT because disposable resources are kernel objects (because they're not necessarily are).
Edit
As Josh Einstein correctly pointed out, finalizers are actually not guaranteed to run on process exit. So then the answer becomes: always call Dispose, just to be sue