IOException: Proses tidak dapat mengakses file 'path file' karena sedang digunakan oleh proses lain

172

Saya memiliki beberapa kode dan ketika dijalankan, ia melempar IOException, mengatakan itu

Proses tidak dapat mengakses file 'nama file' karena sedang digunakan oleh proses lain

Apa artinya ini, dan apa yang bisa saya lakukan?

Adriano Repetti
sumber
1
Lihat pertanyaan ini untuk cara menemukan proses lain yang menggunakan file.
stomy

Jawaban:

274

Apa penyebabnya?

Pesan kesalahannya cukup jelas: Anda mencoba mengakses file, dan itu tidak dapat diakses karena proses lain (atau bahkan proses yang sama) sedang melakukan sesuatu dengannya (dan tidak memungkinkan berbagi apa pun).

Debugging

Mungkin sangat mudah untuk dipecahkan (atau cukup sulit untuk dipahami), tergantung pada skenario spesifik Anda. Mari kita lihat.

Proses Anda adalah satu-satunya untuk mengakses file itu.
Anda yakin proses lainnya adalah proses Anda sendiri. Jika Anda tahu Anda membuka file itu di bagian lain dari program Anda, maka pertama-tama Anda harus memeriksa apakah Anda benar-benar menutup pegangan file setelah setiap kali digunakan. Berikut adalah contoh kode dengan bug ini:

var stream = new FileStream(path, FileAccess.Read);
var reader = new StreamReader(stream);
// Read data from this file, when I'm done I don't need it any more
File.Delete(path); // IOException: file is in use

Untungnya FileStreamimplementasinya IDisposable, jadi mudah untuk membungkus semua kode Anda di dalam usingpernyataan:

using (var stream = File.Open("myfile.txt", FileMode.Open)) {
    // Use stream
}

// Here stream is not accessible and it has been closed (also if
// an exception is thrown and stack unrolled

Pola ini juga akan memastikan bahwa file tidak akan dibiarkan terbuka jika ada pengecualian (mungkin itu alasan file digunakan: ada yang tidak beres, dan tidak ada yang menutupnya; lihat posting ini sebagai contoh).

Jika semuanya tampak baik-baik saja (Anda yakin Anda selalu menutup setiap file yang Anda buka, bahkan dalam kasus pengecualian) dan Anda memiliki beberapa utas yang berfungsi, maka Anda memiliki dua opsi: pengerjaan ulang kode Anda untuk membuat serial akses file (tidak selalu bisa dilakukan dan tidak selalu ingin) atau menerapkan pola coba lagi . Ini adalah pola yang cukup umum untuk operasi I / O: Anda mencoba melakukan sesuatu dan jika terjadi kesalahan Anda menunggu dan mencoba lagi (apakah Anda bertanya pada diri sendiri mengapa, misalnya, Windows Shell membutuhkan waktu untuk memberi tahu Anda bahwa file sedang digunakan dan tidak bisa dihapus?). Di C # ini cukup mudah untuk diterapkan (lihat juga contoh yang lebih baik tentang disk I / O , jaringan dan akses basis data ).

private const int NumberOfRetries = 3;
private const int DelayOnRetry = 1000;

for (int i=1; i <= NumberOfRetries; ++i) {
    try {
        // Do stuff with file
        break; // When done we can break loop
    }
    catch (IOException e) when (i <= NumberOfRetries) {
        // You may check error code to filter some exceptions, not every error
        // can be recovered.
        Thread.Sleep(DelayOnRetry);
    }
}

Harap perhatikan kesalahan umum yang sering kita lihat di StackOverflow:

var stream = File.Open(path, FileOpen.Read);
var content = File.ReadAllText(path);

Dalam hal ini ReadAllText()akan gagal karena file sedang digunakan ( File.Open()di baris sebelumnya). Untuk membuka file sebelumnya tidak hanya tidak perlu tetapi juga salah. Hal yang sama berlaku untuk semua Filefungsi yang tidak mengembalikan pegangan ke file Anda bekerja dengan: File.ReadAllText(), File.WriteAllText(), File.ReadAllLines(), File.WriteAllLines()dan lain-lain (seperti File.AppendAllXyz()fungsi) semua akan membuka dan menutup file sendiri.

Proses Anda bukan satu-satunya untuk mengakses file itu.
Jika proses Anda bukan satu-satunya untuk mengakses file itu, maka interaksi bisa lebih sulit. Sebuah pola coba lagi akan membantu (jika file tersebut tidak harus terbuka oleh orang lain tetapi, maka Anda memerlukan utilitas seperti Process Explorer untuk memeriksa siapa yang melakukan apa ).

Cara yang harus dihindari

Jika berlaku, selalu gunakan menggunakan pernyataan untuk membuka file. Seperti yang disebutkan pada paragraf sebelumnya, ini akan secara aktif membantu Anda menghindari banyak kesalahan umum (lihat posting ini untuk contoh tentang bagaimana tidak menggunakannya ).

Jika memungkinkan, cobalah untuk memutuskan siapa yang memiliki akses ke file tertentu dan memusatkan akses melalui beberapa metode terkenal. Jika, misalnya, Anda memiliki file data di mana program Anda membaca dan menulis, maka Anda harus memasukkan semua kode I / O di dalam satu kelas. Ini akan membuat debug lebih mudah (karena Anda selalu dapat meletakkan breakpoint di sana dan melihat siapa yang melakukan apa) dan juga itu akan menjadi titik sinkronisasi (jika diperlukan) untuk beberapa akses.

Jangan lupa operasi I / O selalu bisa gagal, contoh umum adalah ini:

if (File.Exists(path))
    File.Delete(path);

Jika seseorang menghapus file setelah File.Exists()tetapi sebelumnya File.Delete(), maka itu akan melempar IOExceptiondi tempat di mana Anda salah merasa aman.

Kapan pun memungkinkan, terapkan pola coba lagi , dan jika Anda menggunakan FileSystemWatcher, pertimbangkan untuk menunda tindakan (karena Anda akan diberi tahu, tetapi aplikasi mungkin masih bekerja secara eksklusif dengan file itu).

Skenario lanjutan
Ini tidak selalu mudah, jadi Anda mungkin perlu berbagi akses dengan orang lain. Jika, misalnya, Anda membaca dari awal dan menulis hingga akhir, Anda memiliki setidaknya dua opsi.

1) berbagi hal yang sama FileStreamdengan fungsi sinkronisasi yang tepat (karena tidak aman untuk thread ). Lihat ini dan posting ini sebagai contoh.

2) menggunakan FileShareenumerasi untuk menginstruksikan OS untuk memungkinkan proses lain (atau bagian lain dari proses Anda sendiri) untuk mengakses file yang sama secara bersamaan.

using (var stream = File.Open(path, FileMode.Open, FileAccess.Write, FileShare.Read))
{
}

Dalam contoh ini saya menunjukkan cara membuka file untuk ditulis dan dibagikan untuk dibaca; harap dicatat bahwa ketika membaca dan menulis tumpang tindih, itu menghasilkan data yang tidak terdefinisi atau tidak valid. Ini adalah situasi yang harus ditangani ketika membaca. Perhatikan juga bahwa ini tidak membuat akses ke streamthread-safe, jadi objek ini tidak dapat dibagi dengan banyak utas kecuali jika akses entah bagaimana disinkronkan (lihat tautan sebelumnya). Opsi berbagi lainnya tersedia, dan mereka membuka skenario yang lebih kompleks. Silakan merujuk ke MSDN untuk detail lebih lanjut.

Secara umum N proses dapat membaca dari file yang sama secara bersamaan, tetapi hanya satu yang harus menulis, dalam skenario terkontrol Anda bahkan dapat mengaktifkan tulisan bersamaan tetapi ini tidak dapat digeneralisasi dalam beberapa paragraf teks di dalam jawaban ini.

Apakah mungkin untuk membuka kunci file yang digunakan oleh proses lain? Itu tidak selalu aman dan tidak begitu mudah tetapi ya, itu mungkin .

Adriano Repetti
sumber
Saya tidak tahu apa yang salah dengan kode saya, saya menggunakan blok, tetapi masih ada kesalahan mengatakan file sedang digunakan ketika saya mencoba untuk menghapusnya.
Jamshaid Kamran
Tidak, Sebenarnya saya memiliki kontrol pengatur waktu yang melakukan hal itu, di samping pengatur waktu, jika saya memanggil fungsi itu lagi ia akan melempar pengecualian. pada dasarnya saya mendekripsi file ke file teks lain, setelah itu menghapus file yang baru dibuat ,, yang melempar pengecualian pada penghapusan!
Jamshaid Kamran
3
@ جمشیدکامران Mengapa membuat file dengan konten yang Anda miliki di kode Anda, lalu hapus? Tampaknya aneh untuk membuat file di tempat pertama, lalu. Karena Anda tidak memposting kode, kami tidak tahu apa yang Anda lakukan. Tetapi ketika Anda membuat file Anda, jika Anda melakukannya dengan File.Create(path), Anda harus menambahkan .Close()di akhir itu sebelum Anda menulisnya. Ada jebakan seperti itu, selain usingpernyataan untuk menulis file, kemudian menghapusnya. Anda harus memposting kode dalam pertanyaan Anda untuk bagaimana Anda membuat & menghapus file Anda. Tetapi mungkin sejalan dengan sesuatu yang disebutkan di atas.
vapcguy
Kode saya menggunakan Directory.SetCreationTimeUTC()tetapi gagal ketika File Explorer terbuka, mengklaim direktori sedang diakses oleh proses lain. Bagaimana saya harus menangani situasi ini?
Kyle Delaney
1
@KyleDelaney Saya akan mengatakan bahwa Anda harus menunggu sampai folder telah ditutup, jika bukan beberapa detik maka semuanya akan cepat menjadi kompleks (membuat antrian latar belakang dengan operasi yang tertunda? Pengawas sistem file? Polling?) Anda mungkin ingin memposting pertanyaan dengan rincian lebih lanjut untuk jawaban ad-hoc
Adriano Repetti
29

Menggunakan FileShare memperbaiki masalah saya membuka file bahkan jika dibuka oleh proses lain.

using (var stream = File.Open(path, FileMode.Open, FileAccess.Write, FileShare.ReadWrite))
{
}
Muhammad Umar
sumber
9

Mengalami masalah saat mengunggah gambar dan tidak dapat menghapusnya dan menemukan solusinya. gl hf

//C# .NET
var image = Image.FromFile(filePath);

image.Dispose(); // this removes all resources

//later...

File.Delete(filePath); //now works
Hudson
sumber
2
Jika Anda menghapus file, Anda harus membuang objek gambar terlebih dahulu.
shazia
1
Bagus, saya mencari solusi ini. Saya juga punya masalah dengan fungsi Image.FromFile.
keturunan
1
@thescion :) np
Hudson
1
Ini bekerja dengan baik untuk saya dan menyelesaikan masalah saya yang sebenarnya. Saya ingin memproses folder file Tiff, mengonversinya menjadi stream byte [] dan mengirim ke layanan, dan kemudian memindahkan folder file Tiff ke folder arsip "Diproses". Image.FromFile menempatkan kunci pada file Tiff, dan tidak melepaskannya tepat waktu, jadi ketika saya pergi untuk memindahkan file Tiff dan folder yang berisi, saya akan mendapatkan kesalahan "sedang digunakan oleh proses lain", karena kunci masih di tempat. Melakukan .Release segera setelah mendapatkan byte dari file Tiff benar-benar memperbaiki masalah file yang terkunci ini.
Developer63
4

Saya mendapat kesalahan ini karena saya sedang melakukan File.Move ke path file tanpa nama file, perlu menentukan path lengkap di tujuan.

cinta hidup
sumber
Dan bukan hanya tanpa nama file. Nama file ilegal (tujuan) - dalam kasus saya "... \ file." - akan memberikan kesalahan bodoh yang sama ini dan mengarahkan Anda ke arah yang salah selama setengah hari!
Nick Westgate
3

Kesalahan menunjukkan proses lain sedang mencoba mengakses file. Mungkin Anda atau orang lain membukanya saat Anda mencoba menulisnya. "Baca" atau "Salin" biasanya tidak menyebabkan ini, tetapi menulis ke sana atau memanggil delete akan membuatnya.

Ada beberapa hal mendasar untuk menghindari ini, seperti jawaban lain telah disebutkan:

  1. Dalam FileStreamoperasi, letakkan di usingblok dengan FileShare.ReadWritemode akses.

    Sebagai contoh:

    using (FileStream stream = File.Open(path, FileMode.Open, FileAccess.Write, FileShare.ReadWrite))
    {
    }
    

    Catatan yang FileAccess.ReadWritetidak mungkin jika Anda gunakan FileMode.Append.

  2. Saya mengalami masalah ini ketika saya menggunakan aliran input untuk melakukan File.SaveAsketika file sedang digunakan. Dalam kasus saya yang saya temukan, saya sebenarnya tidak perlu menyimpannya kembali ke sistem file sama sekali, jadi saya akhirnya hanya menghapus itu, tapi saya mungkin bisa mencoba membuat FileStream dalam sebuah usingpernyataan dengan FileAccess.ReadWrite, seperti kode atas.

  3. Menyimpan data Anda sebagai file yang berbeda dan kembali untuk menghapus yang lama ketika ternyata tidak lagi digunakan, kemudian mengganti nama yang berhasil disimpan dengan nama yang asli adalah pilihan. Bagaimana Anda menguji file yang sedang digunakan dicapai melalui

    List<Process> lstProcs = ProcessHandler.WhoIsLocking(file);

    baris dalam kode saya di bawah ini, dan dapat dilakukan dalam layanan Windows, dalam satu lingkaran, jika Anda memiliki file tertentu yang ingin Anda tonton dan hapus secara teratur ketika Anda ingin menggantinya. Jika Anda tidak selalu memiliki file yang sama, file teks atau tabel database dapat diperbarui bahwa layanan selalu memeriksa nama file, dan kemudian melakukan itu memeriksa proses & selanjutnya melakukan proses membunuh dan menghapusnya, seperti yang saya jelaskan di opsi selanjutnya. Perhatikan bahwa Anda akan memerlukan nama pengguna dan kata sandi akun yang memiliki hak Admin di komputer yang diberikan, tentu saja, untuk melakukan penghapusan dan proses akhir.

  4. Ketika Anda tidak tahu apakah suatu file akan digunakan ketika Anda mencoba untuk menyimpannya, Anda bisa menutup semua proses yang bisa menggunakannya, seperti Word, jika itu dokumen Word, di depan save.

    Jika lokal, Anda dapat melakukan ini:

    ProcessHandler.localProcessKill("winword.exe");

    Jika jarak jauh, Anda dapat melakukan ini:

    ProcessHandler.remoteProcessKill(computerName, txtUserName, txtPassword, "winword.exe");

    di mana txtUserNamedalam bentuk DOMAIN\user.

  5. Katakanlah Anda tidak tahu nama proses yang mengunci file. Kemudian, Anda dapat melakukan ini:

    List<Process> lstProcs = new List<Process>();
    lstProcs = ProcessHandler.WhoIsLocking(file);
    
    foreach (Process p in lstProcs)
    {
        if (p.MachineName == ".")
            ProcessHandler.localProcessKill(p.ProcessName);
        else
            ProcessHandler.remoteProcessKill(p.MachineName, txtUserName, txtPassword, p.ProcessName);
    }

    Catatan yang fileharus menjadi jalur UNC: \\computer\share\yourdoc.docxagar Processdapat mengetahui komputer apa yang aktif dan p.MachineNamevalid.

    Di bawah ini adalah kelas yang digunakan fungsi-fungsi ini, yang membutuhkan penambahan referensi System.Management. Kode ini awalnya ditulis oleh Eric J .:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Runtime.InteropServices;
    using System.Diagnostics;
    using System.Management;
    
    namespace MyProject
    {
        public static class ProcessHandler
        {
            [StructLayout(LayoutKind.Sequential)]
            struct RM_UNIQUE_PROCESS
            {
                public int dwProcessId;
                public System.Runtime.InteropServices.ComTypes.FILETIME ProcessStartTime;
            }
    
            const int RmRebootReasonNone = 0;
            const int CCH_RM_MAX_APP_NAME = 255;
            const int CCH_RM_MAX_SVC_NAME = 63;
    
            enum RM_APP_TYPE
            {
                RmUnknownApp = 0,
                RmMainWindow = 1,
                RmOtherWindow = 2,
                RmService = 3,
                RmExplorer = 4,
                RmConsole = 5,
                RmCritical = 1000
            }
    
            [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
            struct RM_PROCESS_INFO
            {
                public RM_UNIQUE_PROCESS Process;
    
                [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCH_RM_MAX_APP_NAME + 1)]
                public string strAppName;
    
                [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCH_RM_MAX_SVC_NAME + 1)]
                public string strServiceShortName;
    
                public RM_APP_TYPE ApplicationType;
                public uint AppStatus;
                public uint TSSessionId;
                [MarshalAs(UnmanagedType.Bool)]
                public bool bRestartable;
            }
    
            [DllImport("rstrtmgr.dll", CharSet = CharSet.Unicode)]
            static extern int RmRegisterResources(uint pSessionHandle,
                                                UInt32 nFiles,
                                                string[] rgsFilenames,
                                                UInt32 nApplications,
                                                [In] RM_UNIQUE_PROCESS[] rgApplications,
                                                UInt32 nServices,
                                                string[] rgsServiceNames);
    
            [DllImport("rstrtmgr.dll", CharSet = CharSet.Auto)]
            static extern int RmStartSession(out uint pSessionHandle, int dwSessionFlags, string strSessionKey);
    
            [DllImport("rstrtmgr.dll")]
            static extern int RmEndSession(uint pSessionHandle);
    
            [DllImport("rstrtmgr.dll")]
            static extern int RmGetList(uint dwSessionHandle,
                                        out uint pnProcInfoNeeded,
                                        ref uint pnProcInfo,
                                        [In, Out] RM_PROCESS_INFO[] rgAffectedApps,
                                        ref uint lpdwRebootReasons);
    
            /// <summary>
            /// Find out what process(es) have a lock on the specified file.
            /// </summary>
            /// <param name="path">Path of the file.</param>
            /// <returns>Processes locking the file</returns>
            /// <remarks>See also:
            /// http://msdn.microsoft.com/en-us/library/windows/desktop/aa373661(v=vs.85).aspx
            /// http://wyupdate.googlecode.com/svn-history/r401/trunk/frmFilesInUse.cs (no copyright in code at time of viewing)
            /// 
            /// </remarks>
            static public List<Process> WhoIsLocking(string path)
            {
                uint handle;
                string key = Guid.NewGuid().ToString();
                List<Process> processes = new List<Process>();
    
                int res = RmStartSession(out handle, 0, key);
                if (res != 0) throw new Exception("Could not begin restart session.  Unable to determine file locker.");
    
                try
                {
                    const int ERROR_MORE_DATA = 234;
                    uint pnProcInfoNeeded = 0,
                        pnProcInfo = 0,
                        lpdwRebootReasons = RmRebootReasonNone;
    
                    string[] resources = new string[] { path }; // Just checking on one resource.
    
                    res = RmRegisterResources(handle, (uint)resources.Length, resources, 0, null, 0, null);
    
                    if (res != 0) throw new Exception("Could not register resource.");
    
                    //Note: there's a race condition here -- the first call to RmGetList() returns
                    //      the total number of process. However, when we call RmGetList() again to get
                    //      the actual processes this number may have increased.
                    res = RmGetList(handle, out pnProcInfoNeeded, ref pnProcInfo, null, ref lpdwRebootReasons);
    
                    if (res == ERROR_MORE_DATA)
                    {
                        // Create an array to store the process results
                        RM_PROCESS_INFO[] processInfo = new RM_PROCESS_INFO[pnProcInfoNeeded];
                        pnProcInfo = pnProcInfoNeeded;
    
                        // Get the list
                        res = RmGetList(handle, out pnProcInfoNeeded, ref pnProcInfo, processInfo, ref lpdwRebootReasons);
                        if (res == 0)
                        {
                            processes = new List<Process>((int)pnProcInfo);
    
                            // Enumerate all of the results and add them to the 
                            // list to be returned
                            for (int i = 0; i < pnProcInfo; i++)
                            {
                                try
                                {
                                    processes.Add(Process.GetProcessById(processInfo[i].Process.dwProcessId));
                                }
                                // catch the error -- in case the process is no longer running
                                catch (ArgumentException) { }
                            }
                        }
                        else throw new Exception("Could not list processes locking resource.");
                    }
                    else if (res != 0) throw new Exception("Could not list processes locking resource. Failed to get size of result.");
                }
                finally
                {
                    RmEndSession(handle);
                }
    
                return processes;
            }
    
            public static void remoteProcessKill(string computerName, string userName, string pword, string processName)
            {
                var connectoptions = new ConnectionOptions();
                connectoptions.Username = userName;
                connectoptions.Password = pword;
    
                ManagementScope scope = new ManagementScope(@"\\" + computerName + @"\root\cimv2", connectoptions);
    
                // WMI query
                var query = new SelectQuery("select * from Win32_process where name = '" + processName + "'");
    
                using (var searcher = new ManagementObjectSearcher(scope, query))
                {
                    foreach (ManagementObject process in searcher.Get()) 
                    {
                        process.InvokeMethod("Terminate", null);
                        process.Dispose();
                    }
                }            
            }
    
            public static void localProcessKill(string processName)
            {
                foreach (Process p in Process.GetProcessesByName(processName))
                {
                    p.Kill();
                }
            }
    
            [DllImport("kernel32.dll")]
            public static extern bool MoveFileEx(string lpExistingFileName, string lpNewFileName, int dwFlags);
    
            public const int MOVEFILE_DELAY_UNTIL_REBOOT = 0x4;
    
        }
    }
vapcguy
sumber
2

Seperti yang ditunjukkan oleh jawaban lain di utas ini, untuk menyelesaikan kesalahan ini Anda perlu memeriksa kode dengan hati-hati, untuk memahami di mana file terkunci.

Dalam kasus saya, saya mengirim file sebagai lampiran email sebelum melakukan operasi pemindahan.

Jadi file terkunci selama beberapa detik sampai klien SMTP selesai mengirim email.

Solusi yang saya adopsi adalah memindahkan file terlebih dahulu, dan kemudian mengirim email. Ini memecahkan masalah bagi saya.

Solusi lain yang mungkin, seperti yang ditunjukkan sebelumnya oleh Hudson, adalah membuang benda setelah digunakan.

public static SendEmail()
{
           MailMessage mMailMessage = new MailMessage();
           //setup other email stuff

            if (File.Exists(attachmentPath))
            {
                Attachment attachment = new Attachment(attachmentPath);
                mMailMessage.Attachments.Add(attachment);
                attachment.Dispose(); //disposing the Attachment object
            }
} 
Abhishek Poojary
sumber
Jika file sedang digunakan File.Move()tidak akan berfungsi & memberikan kesalahan yang sama. Jika hanya menambahkan file ke email saya tidak berpikir itu kesalahan saat digunakan selama Attachments.Add()operasi karena ini hanya operasi salin. Jika itu dilakukan karena alasan tertentu Anda bisa menyalinnya ke direktori Temp, lampirkan salinannya, & hapus file yang disalin sesudahnya. Tapi saya tidak berpikir, jika OP ingin memodifikasi file & menggunakannya, solusi semacam ini (yang Anda tidak menunjukkan kode, hanya bagian yang dilampirkan) akan berfungsi. .Dispose()selalu merupakan ide yang baik, tetapi tidak relevan di sini kecuali file dibuka di op sebelumnya.
vapcguy
1

Saya memiliki skenario berikut yang menyebabkan kesalahan yang sama:

  • Unggah file ke server
  • Kemudian singkirkan file lama setelah diunggah

Sebagian besar file berukuran kecil, namun ada pula yang berukuran besar, sehingga berusaha menghapusnya menyebabkan tidak dapat mengakses kesalahan file .

Itu tidak mudah ditemukan, namun, solusinya sesederhana Menunggu "untuk tugas untuk menyelesaikan eksekusi":

using (var wc = new WebClient())
{
   var tskResult = wc.UploadFileTaskAsync(_address, _fileName);
   tskResult.Wait(); 
}
BermanfaatBee
sumber
-1

Kode saya di bawah ini menyelesaikan masalah ini, tetapi saya sarankan Pertama-tama Anda perlu memahami apa yang menyebabkan masalah ini dan mencoba solusi yang dapat Anda temukan dengan mengubah kode

Saya dapat memberikan cara lain untuk mengatasi masalah ini, tetapi solusi yang lebih baik adalah dengan memeriksa struktur pengkodean Anda dan mencoba menganalisis apa yang menyebabkan hal ini terjadi, jika Anda tidak menemukan solusi apa pun, Anda dapat menggunakan kode ini di bawah ini.

try{
Start:
///Put your file access code here


}catch (Exception ex)
 {
//by anyway you need to handle this error with below code
   if (ex.Message.StartsWith("The process cannot access the file"))
    {
         //Wait for 5 seconds to free that file and then start execution again
         Thread.Sleep(5000);
         goto Start;
    }
 }
Abu
sumber
1
Beberapa masalah dengan kode ini: 1) jika Anda perlu menelepon GC.*()maka Anda mungkin memiliki masalah lain dengan kode Anda. 2) Pesan dilokalkan dan rapuh , gunakan HRESULT sebagai gantinya. 3) Anda mungkin ingin tidur dengan Task.Delay()(dan sepuluh detik entah bagaimana berlebihan dalam banyak kasus). 4) Anda tidak memiliki kondisi keluar: kode ini bisa hang forver. 5) Anda pasti tidak perlu di gotosini. 6) Menangkap Exceptionbiasanya merupakan ide yang buruk, dalam hal ini juga karena ... 6) Jika ada hal lain terjadi maka Anda menelan kesalahan.
Adriano Repetti
@AdrianoRepetti komentar pertama saya mengatakan jangan gunakan kode ini, coba cari solusi lain, ini akan menjadi opsi terakhir dan bagaimanapun, jika kesalahan ini terjadi, kode akan dihentikan tetapi jika Anda menangani sistem kesalahan ini akan menunggu untuk membebaskan file dan setelah itu akan mulai berfungsi dan saya tidak menghadapi masalah lain dengan GC. * saat menggunakan kode ini. saya sudah memiliki sistem kerja dengan kode ini sehingga saya diposting mungkin dapat membantu seseorang.
Ash
Saya akan mengatakan untuk tidak menggunakan kode ini pernah (karena poin yang saya sebutkan di atas) dan saya tidak akan mempertimbangkan ini bekerja dalam sistem prod tapi itu hanya POV saya. Jangan ragu untuk tidak setuju!
Adriano Repetti
1) Saya menggunakan layanan windows di mana saya mengkonsumsi ini dan saya menggunakan GC. * Sampai ini saya tidak menghadapi masalah dengan ini2) ya HRESULT bisa menjadi pilihan yang lebih baik dalam hal pengkodean standar3) Tergantung pada situasi Anda dapat memberikan waktu saya baru saja diedit hingga 5 detik 4) bagaimanapun, lebih baik sistem menunggu waktu untuk membebaskan sumber daya daripada menghentikan sistem dengan kesalahan 5) ya saya setuju dengan Anda pengecualian penanganan tidak selalu ide yang baik tetapi jika cuplikan kode Anda kecil dan Anda tahu bahwa di sini saya dapat menangani pengecualian maka solusi ini adalah pilihan untuk Anda.
Ash
Lihat juga: docs.microsoft.com/en-us/archive/blogs/ricom/… . Kasus ONLY (dan saya menekankan ONLY) yang perlu saya gunakan GC.Collect()adalah ketika berurusan dengan beberapa objek COM.
Adriano Repetti