Reputation: 495
I read a lot about SafeFileHandle
and from what I've seen I think I don't have to use it or it doesn't have any benefits to use it in FileStream
because it is closed by first object of file stream handled it and I can't use it in another objects.
Can any one tell me when should I use it?
static void Main(string[] args)
{
string path = "Hello";
SafeFileHandle handle = File.Open(path, FileMode.OpenOrCreate).SafeFileHandle;
using (FileStream fs = new FileStream(handle, FileAccess.ReadWrite))
{
// do work
}
Console.ReadKey();
}
From what I have seen that definition of SafeFileHandle
is: it is something like a person hold one hand of a rope and they are playing with children, and every child hold the second hand of rope.
person = file handle or any handle (network connection or anything)
rope = SafeFileHandle
kids = objects that want to make operations with file handle like FileStream
This is my perception about safe file handle, is it correct?
Upvotes: 1
Views: 1468
Reputation: 70661
The overloads that accept SafeFileHandle
exist for the same reason that the now-obsolete overloads that accepted an IntPtr
did: so that you can construct a new FileStream
instance from a file handle that you obtained through p/invoke interop, i.e. from unmanaged code.
The SafeHandle
type and idiom for its use did not exist in the earliest versions of .NET. Raw IntPtr
values were used any time managed code needed to deal with native handles. When the much better SafeHandle
type was introduced, it simply made sense to provide specific subclasses for commonly-used native handle types, like file handles, and then to support those specific subclasses in any managed API, including constructors like those for FileStream
, where the native handle type previously was used.
The example you've provided would never (or at least, should never) appear in real-world code. If you are opening a file from managed code and using it only in managed code, then you just do that. You never have any reason to mess with the native file handle at all. You would use the SafeFileHandle
property of a FileStream
object only if you needed to pass the native file handle to unmanaged code, and you would pass a SafeFileHandle
value to the FileStream
constructor only if you had no way to obtain that particular file handle except from unmanaged code.
Frankly, I don't really understand your analogy with the rope and children. It doesn't seem correct or useful to me though. You already got an answer to your previous, very broad question What is SafeFileHandle in c# and when should i use?, so you should already know why SafeFileHandle
exists, but to recap here:
SafeHandle
, and its subclasses, are provided as a much-better alternative to having to make one's class deal with finalizers. The SafeHandle
class itself implements the finalization logic, so your class doesn't have do. At least, as long as the only unmanaged objects your class would normally deal with can be wrapped in a SafeHandle
subclass — and since you can implement your own wrappers, for those objects that don't already have a .NET-provided wrapper, this should be all of your unmanaged objects — then you don't need a finalizer. (You still need to implement IDisposable
, so that your unmanaged objects can be cleaned up deterministically…the finalizer is solely there as a backup).I hope that the above is sufficient to explain all this. Stack Overflow isn't really the right place for extensive, tutorial level explanations of concepts. But, assuming the above short discussion provides the level of detail you needed to understand why those constructors exist, that seems fine to me.
Upvotes: 3