none
FileIO Exception File in use RRS feed

  • Question

  •  

    Howdy,

     

    I am getting a generic FileIO exception when I have 2 processes trying to 'touch' the same file.

    I want to catch only that exception so that I can wait and try again.

    Is there a current work around to catch only this exception?

    May I request that this type of exception be added to the next .net version (that is, if it is not already there and I missed something)?

     

    Exception type: IOException

    Exception message: The process cannot access the file 'C:\foo.jpg' because it is being used by another process.

     

    Thanks, Johnathan

    Tuesday, March 18, 2008 9:59 PM

Answers

  • Unfortunately, there does not seem to be a "supported" way to do this.

     

    Here is an "unsupported" way.

     

    Notice that the (protected) HResult property of the exception is hexadecimal 0x80070020.

     

    The 0x8007 tells us that this is a failure result and that the second half will be a Win32 error code.  (http://en.wikipedia.org/wiki/HRESULT)

     

    Executing NET HELPMSG 32 (the decimal for 0x0020) tells us that the error message is "The process cannot access the file because it is being used by another process.", so the HResult is telling us what we need to know.

     

    Therefore:

     

    Code Snippet

    bool success = false;

    while (!success)

    {

    try

    {

    using (System.IO.FileStream fs = System.IO.File.Open(

    "c:\\test.txt", System.IO.FileMode.Open))

    {

    // Code to process file here.

    success = true;

    }

    }

    catch (System.IO.IOException ex)

    {

    int hr = (int)ex.GetType().GetProperty("HResult",

    System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic)

    .GetValue(ex, null);

     

    if (hr == -2147024864)

    {

    System.Threading.Thread.Sleep(1000); // Wait a second.

    }

    else

    {

    throw; // Not an exception we recognize; rethrow.

    }

    }

     

     

     

    Wednesday, March 19, 2008 12:52 AM

All replies

  • Unfortunately, there does not seem to be a "supported" way to do this.

     

    Here is an "unsupported" way.

     

    Notice that the (protected) HResult property of the exception is hexadecimal 0x80070020.

     

    The 0x8007 tells us that this is a failure result and that the second half will be a Win32 error code.  (http://en.wikipedia.org/wiki/HRESULT)

     

    Executing NET HELPMSG 32 (the decimal for 0x0020) tells us that the error message is "The process cannot access the file because it is being used by another process.", so the HResult is telling us what we need to know.

     

    Therefore:

     

    Code Snippet

    bool success = false;

    while (!success)

    {

    try

    {

    using (System.IO.FileStream fs = System.IO.File.Open(

    "c:\\test.txt", System.IO.FileMode.Open))

    {

    // Code to process file here.

    success = true;

    }

    }

    catch (System.IO.IOException ex)

    {

    int hr = (int)ex.GetType().GetProperty("HResult",

    System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic)

    .GetValue(ex, null);

     

    if (hr == -2147024864)

    {

    System.Threading.Thread.Sleep(1000); // Wait a second.

    }

    else

    {

    throw; // Not an exception we recognize; rethrow.

    }

    }

     

     

     

    Wednesday, March 19, 2008 12:52 AM
  • Works like a charm!

     

    thanks!

     

    Thursday, April 3, 2008 11:25 PM
  • Jason, I'm not sure if this has been changed since you wrote your original post, but HResult is a public member of the System.IO.IOException class. Therefore, you do not need Reflection to access it.
    • Edited by Tom Lint Tuesday, October 27, 2015 1:15 PM Cleared-up reference
    Tuesday, October 27, 2015 1:15 PM