|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
FileStream.Close() Exception - How to release the lock?Using .NET v2.0.50727, I've attached some sample code that creates a file in a network path (test.er-1): - The file is created at a network path. - The user disconnects his/her network cable. - The file is attempted to write to. - The user reconnects his/her network cable. - The file is closed - WHICH fails and results in the exception "The handle is invalid" This results in that the filelock remain active until the process is terminated... Any suggestions on how to close the file in the same scenario? Best Regards, Fredrik Johansson [code] private FileStream fs1; public void Runme() { lock (this) { string networkFile = @"\\anyserver\anyshare\test.er-"; // open the file Console.Write("Creating Files (OK expected)..."); try { fs1 = new FileStream(networkFile + "1", FileMode.CreateNew, FileAccess.Write, FileShare.Read); Console.WriteLine("OK"); } catch (Exception e) { Console.WriteLine("FAILED\r\nThe test can not be performed. Please modify the networkFile parameter!"); Console.WriteLine("\r\nPress ENTER to exit..."); Console.ReadLine(); return; } // wait for user to disconnect Console.Write("Please disconnect from your network, press ENTER to continue..."); Console.ReadLine(); // try to write some data - this will fail try { Console.Write("Attempting to Write (FAILED expected)..."); byte[] ba = Encoding.Default.GetBytes("Hello World"); fs1.Write(ba, 0, ba.Length); fs1.Flush(); Console.WriteLine("OK - Did you really disconnect your drive?"); } catch (Exception e) { Console.WriteLine("FAILED"); } Console.Write("Please connect to your network, press ENTER to continue..."); Console.ReadLine(); // try to close the file - this will fail try { Console.Write("Closing File (this WILL fail)..."); fs1.Close(); fs1 = null; Console.WriteLine("OK - Both files are supposidly closed..."); } catch (Exception e) { // =================================================================== // break here "The handle is invalid" - but the filelock is still on?! Console.WriteLine("FAILED"); } Console.WriteLine("\r\nPress ENTER to exit..."); Console.ReadLine(); } } [/code] You have to close the file prior to disconnecting. You can re-open it
afterwards if you need to. -- Show quoteHTH, Kevin Spencer Microsoft MVP Printing Components, Email Components, Networking Components, Controls, much more. DSI PrintManager, Miradyne Component Libraries: http://www.miradyne.net "Fredrik Johansson" <FredrikJohans***@discussions.microsoft.com> wrote in message news:5853CB7E-940B-4DA3-BBB4-A250672AECDC@microsoft.com... > Hello! > > Using .NET v2.0.50727, I've attached some sample code that creates a file > in > a network path (test.er-1): > - The file is created at a network path. > - The user disconnects his/her network cable. > - The file is attempted to write to. > - The user reconnects his/her network cable. > - The file is closed - WHICH fails and results in the exception "The > handle > is invalid" > > This results in that the filelock remain active until the process is > terminated... Any suggestions on how to close the file in the same > scenario? > > Best Regards, > Fredrik Johansson > > > [code] > private FileStream fs1; > public void Runme() { > lock (this) { > string networkFile = @"\\anyserver\anyshare\test.er-"; > > // open the file > Console.Write("Creating Files (OK expected)..."); > try { > fs1 = new FileStream(networkFile + "1", > FileMode.CreateNew, FileAccess.Write, FileShare.Read); > Console.WriteLine("OK"); > } catch (Exception e) { > Console.WriteLine("FAILED\r\nThe test can not be > performed. Please modify the networkFile parameter!"); > Console.WriteLine("\r\nPress ENTER to exit..."); > Console.ReadLine(); > return; > } > > // wait for user to disconnect > Console.Write("Please disconnect from your network, press > ENTER to continue..."); > Console.ReadLine(); > > // try to write some data - this will fail > try { > Console.Write("Attempting to Write (FAILED > expected)..."); > byte[] ba = Encoding.Default.GetBytes("Hello World"); > fs1.Write(ba, 0, ba.Length); > fs1.Flush(); > Console.WriteLine("OK - Did you really disconnect your > drive?"); > } catch (Exception e) { > Console.WriteLine("FAILED"); > } > > Console.Write("Please connect to your network, press ENTER > to continue..."); > Console.ReadLine(); > > // try to close the file - this will fail > try { > Console.Write("Closing File (this WILL fail)..."); > fs1.Close(); > fs1 = null; > Console.WriteLine("OK - Both files are supposidly > closed..."); > } catch (Exception e) { > // > =================================================================== > // break here "The handle is invalid" - but the > filelock > is still on?! > Console.WriteLine("FAILED"); > } > > Console.WriteLine("\r\nPress ENTER to exit..."); > Console.ReadLine(); > } > } > [/code] And how do you find out when the user (or Windows) decides to disconnect the
network (or perhaps when the DHCP dies)?! We can't have buttons everywhere. I think we need a more robust FileStream, if there isn't any workarounds. Regards Fredrik Show quote "Kevin Spencer" wrote: > You have to close the file prior to disconnecting. You can re-open it > afterwards if you need to. > > -- > HTH, > > Kevin Spencer > Microsoft MVP > > Printing Components, Email Components, > Networking Components, Controls, much more. > DSI PrintManager, Miradyne Component Libraries: > http://www.miradyne.net > > "Fredrik Johansson" <FredrikJohans***@discussions.microsoft.com> wrote in > message news:5853CB7E-940B-4DA3-BBB4-A250672AECDC@microsoft.com... > > Hello! > > > > Using .NET v2.0.50727, I've attached some sample code that creates a file > > in > > a network path (test.er-1): > > - The file is created at a network path. > > - The user disconnects his/her network cable. > > - The file is attempted to write to. > > - The user reconnects his/her network cable. > > - The file is closed - WHICH fails and results in the exception "The > > handle > > is invalid" > > > > This results in that the filelock remain active until the process is > > terminated... Any suggestions on how to close the file in the same > > scenario? > > > > Best Regards, > > Fredrik Johansson > > > > > > [code] > > private FileStream fs1; > > public void Runme() { > > lock (this) { > > string networkFile = @"\\anyserver\anyshare\test.er-"; > > > > // open the file > > Console.Write("Creating Files (OK expected)..."); > > try { > > fs1 = new FileStream(networkFile + "1", > > FileMode.CreateNew, FileAccess.Write, FileShare.Read); > > Console.WriteLine("OK"); > > } catch (Exception e) { > > Console.WriteLine("FAILED\r\nThe test can not be > > performed. Please modify the networkFile parameter!"); > > Console.WriteLine("\r\nPress ENTER to exit..."); > > Console.ReadLine(); > > return; > > } > > > > // wait for user to disconnect > > Console.Write("Please disconnect from your network, press > > ENTER to continue..."); > > Console.ReadLine(); > > > > // try to write some data - this will fail > > try { > > Console.Write("Attempting to Write (FAILED > > expected)..."); > > byte[] ba = Encoding.Default.GetBytes("Hello World"); > > fs1.Write(ba, 0, ba.Length); > > fs1.Flush(); > > Console.WriteLine("OK - Did you really disconnect your > > drive?"); > > } catch (Exception e) { > > Console.WriteLine("FAILED"); > > } > > > > Console.Write("Please connect to your network, press ENTER > > to continue..."); > > Console.ReadLine(); > > > > // try to close the file - this will fail > > try { > > Console.Write("Closing File (this WILL fail)..."); > > fs1.Close(); > > fs1 = null; > > Console.WriteLine("OK - Both files are supposidly > > closed..."); > > } catch (Exception e) { > > // > > =================================================================== > > // break here "The handle is invalid" - but the > > filelock > > is still on?! > > Console.WriteLine("FAILED"); > > } > > > > Console.WriteLine("\r\nPress ENTER to exit..."); > > Console.ReadLine(); > > } > > } > > [/code] > > > You always have those issues, in any application. Rule of thumb when using
File Streams. Open, write, close, as quickly as possible. -- Show quoteHTH, Kevin Spencer Microsoft MVP Printing Components, Email Components, Networking Components, Controls, much more. DSI PrintManager, Miradyne Component Libraries: http://www.miradyne.net "Fredrik Johansson" <FredrikJohans***@discussions.microsoft.com> wrote in message news:D9FB7C42-221C-4DA2-BC4A-0C33FEE5DC18@microsoft.com... > And how do you find out when the user (or Windows) decides to disconnect > the > network (or perhaps when the DHCP dies)?! We can't have buttons > everywhere. I > think we need a more robust FileStream, if there isn't any workarounds. > > > Regards > Fredrik > > "Kevin Spencer" wrote: > >> You have to close the file prior to disconnecting. You can re-open it >> afterwards if you need to. >> >> -- >> HTH, >> >> Kevin Spencer >> Microsoft MVP >> >> Printing Components, Email Components, >> Networking Components, Controls, much more. >> DSI PrintManager, Miradyne Component Libraries: >> http://www.miradyne.net >> >> "Fredrik Johansson" <FredrikJohans***@discussions.microsoft.com> wrote in >> message news:5853CB7E-940B-4DA3-BBB4-A250672AECDC@microsoft.com... >> > Hello! >> > >> > Using .NET v2.0.50727, I've attached some sample code that creates a >> > file >> > in >> > a network path (test.er-1): >> > - The file is created at a network path. >> > - The user disconnects his/her network cable. >> > - The file is attempted to write to. >> > - The user reconnects his/her network cable. >> > - The file is closed - WHICH fails and results in the exception "The >> > handle >> > is invalid" >> > >> > This results in that the filelock remain active until the process is >> > terminated... Any suggestions on how to close the file in the same >> > scenario? >> > >> > Best Regards, >> > Fredrik Johansson >> > >> > >> > [code] >> > private FileStream fs1; >> > public void Runme() { >> > lock (this) { >> > string networkFile = @"\\anyserver\anyshare\test.er-"; >> > >> > // open the file >> > Console.Write("Creating Files (OK expected)..."); >> > try { >> > fs1 = new FileStream(networkFile + "1", >> > FileMode.CreateNew, FileAccess.Write, FileShare.Read); >> > Console.WriteLine("OK"); >> > } catch (Exception e) { >> > Console.WriteLine("FAILED\r\nThe test can not be >> > performed. Please modify the networkFile parameter!"); >> > Console.WriteLine("\r\nPress ENTER to exit..."); >> > Console.ReadLine(); >> > return; >> > } >> > >> > // wait for user to disconnect >> > Console.Write("Please disconnect from your network, >> > press >> > ENTER to continue..."); >> > Console.ReadLine(); >> > >> > // try to write some data - this will fail >> > try { >> > Console.Write("Attempting to Write (FAILED >> > expected)..."); >> > byte[] ba = Encoding.Default.GetBytes("Hello >> > World"); >> > fs1.Write(ba, 0, ba.Length); >> > fs1.Flush(); >> > Console.WriteLine("OK - Did you really disconnect >> > your >> > drive?"); >> > } catch (Exception e) { >> > Console.WriteLine("FAILED"); >> > } >> > >> > Console.Write("Please connect to your network, press >> > ENTER >> > to continue..."); >> > Console.ReadLine(); >> > >> > // try to close the file - this will fail >> > try { >> > Console.Write("Closing File (this WILL fail)..."); >> > fs1.Close(); >> > fs1 = null; >> > Console.WriteLine("OK - Both files are supposidly >> > closed..."); >> > } catch (Exception e) { >> > // >> > =================================================================== >> > // break here "The handle is invalid" - but the >> > filelock >> > is still on?! >> > Console.WriteLine("FAILED"); >> > } >> > >> > Console.WriteLine("\r\nPress ENTER to exit..."); >> > Console.ReadLine(); >> > } >> > } >> > [/code] >> >> >> But even then, that isn't any guarantee that this wouldn't happen. And
besides, that results in terrible performance when you do lots of writing from any app... :) After doing some research I decided to release the lock manually... The trick is to get a copy of the Handle, after the file has been successfully opened: fs1 = new FileStream(...); IntPtr handle = fs1.SafeFileHandle.DangerousGetHandle(); Then when the exception is thrown from the .Close(), all you have to do (to release the lock) is: try { fs1.Close(); } catch (Exception) { CloseHandle(handle); } CloseHandle is an external in kernel32, and imported by using the following statement: [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), DllImport("kernel32.dll", SetLastError = true)] internal static extern bool CloseHandle(IntPtr handle); Attribute namespaces are located in System.Runtime.InteropServices, and System.Runtime.ConstrainedExecution. Of course, one would think that FileStream (which by the way - is a great class) could recover from this by itself, without any help from the coder. It's not the 1900 anymore :) Regards, Fredrik Show quote "Kevin Spencer" wrote: > You always have those issues, in any application. Rule of thumb when using > File Streams. Open, write, close, as quickly as possible. > > -- > HTH, > > Kevin Spencer > Microsoft MVP > > Printing Components, Email Components, > Networking Components, Controls, much more. > DSI PrintManager, Miradyne Component Libraries: > http://www.miradyne.net > > "Fredrik Johansson" <FredrikJohans***@discussions.microsoft.com> wrote in > message news:D9FB7C42-221C-4DA2-BC4A-0C33FEE5DC18@microsoft.com... > > And how do you find out when the user (or Windows) decides to disconnect > > the > > network (or perhaps when the DHCP dies)?! We can't have buttons > > everywhere. I > > think we need a more robust FileStream, if there isn't any workarounds. > > > > > > Regards > > Fredrik > > > > "Kevin Spencer" wrote: > > > >> You have to close the file prior to disconnecting. You can re-open it > >> afterwards if you need to. > >> > >> -- > >> HTH, > >> > >> Kevin Spencer > >> Microsoft MVP > >> > >> Printing Components, Email Components, > >> Networking Components, Controls, much more. > >> DSI PrintManager, Miradyne Component Libraries: > >> http://www.miradyne.net > >> > >> "Fredrik Johansson" <FredrikJohans***@discussions.microsoft.com> wrote in > >> message news:5853CB7E-940B-4DA3-BBB4-A250672AECDC@microsoft.com... > >> > Hello! > >> > > >> > Using .NET v2.0.50727, I've attached some sample code that creates a > >> > file > >> > in > >> > a network path (test.er-1): > >> > - The file is created at a network path. > >> > - The user disconnects his/her network cable. > >> > - The file is attempted to write to. > >> > - The user reconnects his/her network cable. > >> > - The file is closed - WHICH fails and results in the exception "The > >> > handle > >> > is invalid" > >> > > >> > This results in that the filelock remain active until the process is > >> > terminated... Any suggestions on how to close the file in the same > >> > scenario? > >> > > >> > Best Regards, > >> > Fredrik Johansson > >> > > >> > > >> > [code] > >> > private FileStream fs1; > >> > public void Runme() { > >> > lock (this) { > >> > string networkFile = @"\\anyserver\anyshare\test.er-"; > >> > > >> > // open the file > >> > Console.Write("Creating Files (OK expected)..."); > >> > try { > >> > fs1 = new FileStream(networkFile + "1", > >> > FileMode.CreateNew, FileAccess.Write, FileShare.Read); > >> > Console.WriteLine("OK"); > >> > } catch (Exception e) { > >> > Console.WriteLine("FAILED\r\nThe test can not be > >> > performed. Please modify the networkFile parameter!"); > >> > Console.WriteLine("\r\nPress ENTER to exit..."); > >> > Console.ReadLine(); > >> > return; > >> > } > >> > > >> > // wait for user to disconnect > >> > Console.Write("Please disconnect from your network, > >> > press > >> > ENTER to continue..."); > >> > Console.ReadLine(); > >> > > >> > // try to write some data - this will fail > >> > try { > >> > Console.Write("Attempting to Write (FAILED > >> > expected)..."); > >> > byte[] ba = Encoding.Default.GetBytes("Hello > >> > World"); > >> > fs1.Write(ba, 0, ba.Length); > >> > fs1.Flush(); > >> > Console.WriteLine("OK - Did you really disconnect > >> > your > >> > drive?"); > >> > } catch (Exception e) { > >> > Console.WriteLine("FAILED"); > >> > } > >> > > >> > Console.Write("Please connect to your network, press > >> > ENTER > >> > to continue..."); > >> > Console.ReadLine(); > >> > > >> > // try to close the file - this will fail > >> > try { > >> > Console.Write("Closing File (this WILL fail)..."); > >> > fs1.Close(); > >> > fs1 = null; > >> > Console.WriteLine("OK - Both files are supposidly > >> > closed..."); > >> > } catch (Exception e) { > >> > // > >> > =================================================================== > >> > // break here "The handle is invalid" - but the > >> > filelock > >> > is still on?! > >> > Console.WriteLine("FAILED"); > >> > } > >> > > >> > Console.WriteLine("\r\nPress ENTER to exit..."); > >> > Console.ReadLine(); > >> > } > >> > } > >> > [/code] > >> > >> > >> > > > |
|||||||||||||||||||||||