por para laptop juntos instalar discos disco cambiar .net file directory delete-file

.net - para - Extraño comportamiento de borrado de directorio en la unidad SSD



instalar disco ssd y hdd juntos (6)

El directorio c: / test tiene 50 o más archivos en él, no subdirectorios.

If IO.Directory.Exists("C:/test") Then IO.Directory.Delete("C:/test", True) End If IO.Directory.CreateDirectory("C:/test")

La unidad C es la unidad SSD X25-M80 de Intel, el sistema operativo es Windows 7 de 64 bits con soporte TRIM, Visual Studio es 2008 con el marco de destino 3.5. Cuando se ejecuta el código anterior, CreateDirectory interrumpe la ejecución del código sin una excepción (visible). Después de mucho dolor de cabeza, descubrí que la eliminación aún no se realiza cuando el código de tiempo llega a CreateDirectory. Si modifico mi código así:

If IO.Directory.Exists("C:/test") Then IO.Directory.Delete("C:/test", True) End If Threading.Thread.Sleep(2000) IO.Directory.CreateDirectory("C:/test")

entonces todo funciona como se espera.

Mis preguntas junto al WTF obvio aquí son:

  • no debería ser IO.Directory.Delete ser una llamada a la función de bloqueo sin importar cuál sea la unidad
  • ¿SSD está "haciendo trampa" en la eliminación debido a la compatibilidad con TRIM habilitada?

Después de explorar System.IO.Directory con el reflector, parece que .Eliminar es solo una envoltura alrededor de las llamadas a la API de búsqueda FindFirstFile, FindNextFile y RemoveDirectory. No hay nada enlazado o asíncrono acerca de la invocación de esas llamadas a la API en tiempo de ejecución, o la implementación de la API en sí.

Ahora, suponiendo que de alguna manera sea un problema de TRIM, puede deshabilitar TRIM abriendo un símbolo del sistema elevado y usando fsutil:

fsutil behavior set disabledeletenotify 1

Para habilitar, ejecute el mismo comando con 0 como parámetro.

Para consultar, utilice la consulta como el argumento de comando:

fsutil behavior query disabledeletenotify


He tenido problemas con esto antes, pero esto no es específico de las unidades SSD. Sería mucho mejor hacer un movimiento y luego eliminar:

if(Directory.Exists(dirpath)) { string temppath = dirpath + ".deleted"; Directory.Move(dirpath, temppath); Directory.Delete(temppath, true); } Directory.Create(dirpath);

La otra forma de lidiar con esto es hacer un bucle hasta completar:

if(Directory.Exists(dirpath)) { Directory.Delete(dirpath, true); int limit = 100; while(Directory.Exists(dirpath) && limit-- > 0) Thread.Sleep(0); } Directory.Create(dirpath);


Sí, no tiene nada que ver con la unidad SSD. Tuve el mismo problema pero solo en una laptop cliente. Estoy usando .NET 3.5. En mi caso, el directorio tenía un solo archivo. Parece que CreateDirectory se ejecuta primero internamente antes de que finalice Eliminar.

Este fue un código que funcionó bien durante tres años en muchas computadoras. El cliente cambió a una computadora portátil nueva y el código falla constantemente para él. No puedo reproducir el escenario en máquinas de desarrollo / prueba con la misma configuración.


Si ese es realmente el código de la aplicación, ¡tenga en cuenta que realmente está intentando eliminar el directorio llamado "est"!

Escape de su ruta para ser "c: / test" o use @ operator @ "c: / test".


Sospecho que ha encontrado una condición de carrera en NTFS que anteriormente no estaba expuesta, ya que las unidades no existían y eran lo suficientemente rápidas para alcanzarlo. No creo que TRIM tenga nada que ver con esto (¡aunque me reservo el derecho de equivocarme!)

De cualquier manera, la forma correcta de manejar esto es poner el código en un ciclo de Reintento:

int retries = 3; while(true) { try { doTheOperation(); break; } catch (Exception ex) { retries--; if (retries == 0) { throw; } Thread.Sleep(100); continue; } }