/// <summary> /// Workitem 7889: handle ERROR_LOCK_VIOLATION during read /// </summary> /// <remarks> /// This could be gracefully handled with an extension attribute, but /// This assembly is built for .NET 2.0, so I cannot use them. /// </remarks> internal static int ReadWithRetry(System.IO.Stream s, byte[] buffer, int offset, int count, string FileName) { int n = 0; bool done = false; #if !NETCF && !SILVERLIGHT int retries = 0; #endif do { try { n = s.Read(buffer, offset, count); done = true; } #if NETCF || SILVERLIGHT catch (System.IO.IOException) { throw; } #else catch (System.IO.IOException ioexc1) { // Check if we can call GetHRForException, // which makes unmanaged code calls. var p = new System.Security.Permissions.SecurityPermission( System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode); if (p.IsUnrestricted()) { uint hresult = _HRForException(ioexc1); if (hresult != 0x80070021) // ERROR_LOCK_VIOLATION { throw new System.IO.IOException(String.Format("Cannot read file {0}", FileName), ioexc1); } retries++; if (retries > 10) { throw new System.IO.IOException(String.Format("Cannot read file {0}, at offset 0x{1:X8} after 10 retries", FileName, offset), ioexc1); } // max time waited on last retry = 250 + 10*550 = 5.75s // aggregate time waited after 10 retries: 250 + 55*550 = 30.5s System.Threading.Thread.Sleep(250 + retries * 550); } else { // The permission.Demand() failed. Therefore, we cannot call // GetHRForException, and cannot do the subtle handling of // ERROR_LOCK_VIOLATION. Just bail. throw; } } #endif }while (!done); return(n); }
/// <summary> /// Workitem 7889: handle ERROR_LOCK_VIOLATION during read /// </summary> /// <remarks> /// This could be gracefully handled with an extension attribute, but /// This assembly is built for .NET 2.0, so I cannot use them. /// </remarks> internal static int ReadWithRetry(System.IO.Stream s, byte[] buffer, int offset, int count, string FileName) { int n = 0; bool done = false; #if !NETCF && !SILVERLIGHT int retries = 0; #endif do { try { n = s.Read(buffer, offset, count); done = true; } #if NETCF || SILVERLIGHT catch (System.IO.IOException) { throw; } #else catch (System.IO.IOException ioexc1) { // Check if we can call GetHRForException, // which makes unmanaged code calls. var p = new System.Security.Permissions.SecurityPermission( System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode); if (p.IsUnrestricted()) { uint hresult = _HRForException(ioexc1); if (hresult != 0x80070021) // ERROR_LOCK_VIOLATION throw new System.IO.IOException(String.Format("Cannot read file {0}", FileName), ioexc1); retries++; if (retries > 10) throw new System.IO.IOException(String.Format("Cannot read file {0}, at offset 0x{1:X8} after 10 retries", FileName, offset), ioexc1); // max time waited on last retry = 250 + 10*550 = 5.75s // aggregate time waited after 10 retries: 250 + 55*550 = 30.5s System.Threading.Thread.Sleep(250 + retries * 550); } else { // The permission.Demand() failed. Therefore, we cannot call // GetHRForException, and cannot do the subtle handling of // ERROR_LOCK_VIOLATION. Just bail. throw; } } #endif } while (!done); return n; }