หากคุณพยายามที่จะลบไดเรกทอรีซ้ำa
และa\b
เปิดไดเรกทอรีใน Explorer b
จะถูกลบ แต่คุณจะได้รับข้อผิดพลาด 'ไดเรกทอรีไม่ว่าง' a
แม้ว่ามันจะว่างเปล่าเมื่อคุณไปดู ไดเรกทอรีปัจจุบันของโปรแกรมใด ๆ (รวมทั้ง Explorer) ยังคงมีการจัดการไปยังไดเรกทอรี เมื่อคุณเรียกDirectory.Delete(true)
มันลบจากด้านล่างขึ้น: แล้วb
a
หากb
เปิดอยู่ใน Explorer Explorer จะตรวจจับการลบb
เปลี่ยนไดเรกทอรีขึ้นcd ..
และล้างจุดจับเปิด เนื่องจากระบบไฟล์ทำงานแบบอะซิงโครนัสการDirectory.Delete
ดำเนินการล้มเหลวเนื่องจากข้อขัดแย้งกับ Explorer
โซลูชันที่ไม่สมบูรณ์
ฉันโพสต์วิธีแก้ไขปัญหาต่อไปนี้โดยเริ่มต้นด้วยแนวคิดของการขัดจังหวะเธรดปัจจุบันเพื่อให้เวลา Explorer ปล่อยตัวจัดการไดเรกทอรี
// incomplete!
try
{
Directory.Delete(path, true);
}
catch (IOException)
{
Thread.Sleep(0);
Directory.Delete(path, true);
}
แต่นี้จะทำงานเฉพาะถ้าไดเรกทอรีเปิดเป็นทันทีลูกของไดเรกทอรีที่คุณกำลังลบ หากa\b\c\d
มีการเปิดใน Explorer และคุณใช้เกี่ยวกับเรื่องนี้a
เทคนิคนี้จะล้มเหลวหลังจากลบและd
c
ทางออกที่ค่อนข้างดีกว่า
วิธีนี้จะจัดการกับการลบโครงสร้างไดเรกทอรีที่ลึกแม้ว่าหนึ่งในไดเรกทอรีระดับล่างเปิดใน Explorer
/// <summary>
/// Depth-first recursive delete, with handling for descendant
/// directories open in Windows Explorer.
/// </summary>
public static void DeleteDirectory(string path)
{
foreach (string directory in Directory.GetDirectories(path))
{
DeleteDirectory(directory);
}
try
{
Directory.Delete(path, true);
}
catch (IOException)
{
Directory.Delete(path, true);
}
catch (UnauthorizedAccessException)
{
Directory.Delete(path, true);
}
}
แม้จะมีงานพิเศษในการเรียกซ้ำด้วยตัวเอง แต่เราก็ยังต้องจัดการกับสิ่งUnauthorizedAccessException
ที่สามารถเกิดขึ้นได้ตลอดทาง ไม่ชัดเจนว่าความพยายามในการลบครั้งแรกนั้นเป็นการปูทางไปสู่ความสำเร็จครั้งที่สองหรือไม่หรือถ้าเป็นเพียงการหน่วงเวลาตามคำแนะนำจากการขว้างปา / จับข้อยกเว้นที่อนุญาตให้ระบบไฟล์ติดตาม
คุณอาจสามารถลดจำนวนข้อยกเว้นที่ถูกโยนและถูกจับได้ภายใต้เงื่อนไขทั่วไปโดยการเพิ่ม a Thread.Sleep(0)
ที่จุดเริ่มต้นของtry
บล็อก นอกจากนี้ยังมีความเสี่ยงที่ภายใต้ภาระของระบบจำนวนมากคุณสามารถบินผ่านทั้งDirectory.Delete
ความพยายามและความล้มเหลว พิจารณาโซลูชันนี้เป็นจุดเริ่มต้นสำหรับการลบแบบเรียกซ้ำที่มีประสิทธิภาพมากขึ้น
คำตอบทั่วไป
วิธีนี้แก้ไขปัญหาเฉพาะของการโต้ตอบกับ Windows Explorer หากคุณต้องการการลบแบบแข็ง ๆ สิ่งหนึ่งที่ต้องจำไว้ก็คือทุกสิ่ง (ตัวสแกนไวรัสหรืออะไรก็ตาม) อาจมีจุดเปิดแบบเปิดสำหรับสิ่งที่คุณพยายามลบได้ตลอดเวลา ดังนั้นคุณต้องลองอีกครั้งในภายหลัง จำนวนเท่าใดในภายหลังและจำนวนครั้งที่คุณลองขึ้นอยู่กับความสำคัญของวัตถุที่ถูกลบ ในฐานะที่เป็นMSDN บ่งชี้ ,
รหัสการวนซ้ำไฟล์ที่แข็งแกร่งต้องคำนึงถึงความซับซ้อนหลายประการของระบบไฟล์
ข้อความบริสุทธิ์นี้มาพร้อมกับลิงก์ไปยังเอกสารอ้างอิง NTFS เท่านั้นควรทำให้เส้นขนของคุณดูโดดเด่นขึ้น
( แก้ไข : เยอะมากคำตอบนี้มี แต่โซลูชันแรกที่ไม่สมบูรณ์เท่านั้น)