IOException: le processus ne peut pas accéder au fichier 'chemin d'accès au fichier' car il est utilisé par un autre processus

172

J'ai du code et quand il s'exécute, il lance un IOException, disant que

Le processus ne peut pas accéder au fichier 'filename' car il est utilisé par un autre processus

Qu'est-ce que cela signifie et que puis-je faire?

Adriano Repetti
la source
1
Consultez cette question pour savoir comment trouver l'autre processus qui utilise le fichier.
stomie du

Réponses:

274

Quelle est la cause?

Le message d'erreur est assez clair: vous essayez d'accéder à un fichier, et il n'est pas accessible car un autre processus (ou même le même processus) fait quelque chose avec lui (et il n'a permis aucun partage).

Débogage

Cela peut être assez facile à résoudre (ou assez difficile à comprendre), selon votre scénario spécifique. Voyons en voir.

Votre processus est le seul à accéder à ce fichier.
Vous êtes sûr que l' autre processus est votre propre processus. Si vous savez que vous ouvrez ce fichier dans une autre partie de votre programme, vous devez d'abord vérifier que vous fermez correctement le descripteur de fichier après chaque utilisation. Voici un exemple de code avec ce bogue:

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

Heureusement FileStreamimplémente IDisposable, il est donc facile d'encapsuler tout votre code dans une usinginstruction:

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

Ce modèle garantira également que le fichier ne sera pas laissé ouvert en cas d'exceptions (cela peut être la raison pour laquelle le fichier est utilisé: quelque chose s'est mal passé, et personne ne l'a fermé; voir cet article pour un exemple).

Si tout semble bien (vous êtes sûr de toujours fermer tous les fichiers que vous ouvrez, même en cas d'exceptions) et que vous avez plusieurs threads de travail, alors vous avez deux options: retravailler votre code pour sérialiser l'accès aux fichiers (pas toujours faisable et pas toujours voulu) ou appliquez un modèle de nouvelle tentative . C'est un modèle assez courant pour les opérations d'E / S: vous essayez de faire quelque chose et en cas d'erreur, vous attendez et réessayez (vous êtes-vous demandé pourquoi, par exemple, Windows Shell prend un certain temps pour vous informer qu'un fichier est en cours d'utilisation et ne peut pas être supprimé?). En C #, c'est assez facile à implémenter (voir également de meilleurs exemples sur les E / S disque , le réseau et l' accès aux bases de données ).

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);
    }
}

Veuillez noter une erreur courante que nous voyons très souvent sur StackOverflow:

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

Dans ce cas ReadAllText()échouera car le fichier est en cours d'utilisation ( File.Open()dans la ligne précédente). Ouvrir le fichier au préalable n'est pas seulement inutile mais également erroné. De même pour toutes les Filefonctions qui ne renvoient pas une poignée dans le fichier que vous travaillez avec: File.ReadAllText(), File.WriteAllText(), File.ReadAllLines(), File.WriteAllLines()et d' autres (comme les File.AppendAllXyz()fonctions) seront tous ouverts et fermez le fichier par eux - mêmes.

Votre processus n'est pas le seul à accéder à ce fichier
Si votre processus n'est pas le seul à accéder à ce fichier, l'interaction peut être plus difficile. Un modèle de nouvelle tentative aidera (si le fichier ne doit pas être ouvert par quelqu'un d'autre mais qu'il l'est, alors vous avez besoin d'un utilitaire comme Process Explorer pour vérifier qui fait quoi ).

Façons d'éviter

Le cas échéant, utilisez toujours des instructions using pour ouvrir les fichiers. Comme indiqué dans le paragraphe précédent, cela vous aidera activement à éviter de nombreuses erreurs courantes (voir cet article pour un exemple sur la façon de ne pas l'utiliser ).

Si possible, essayez de décider à qui appartient l'accès à un fichier spécifique et centralisez l'accès grâce à quelques méthodes bien connues. Si, par exemple, vous avez un fichier de données dans lequel votre programme lit et écrit, vous devez insérer tout le code d'E / S dans une seule classe. Cela facilitera le débogage (car vous pouvez toujours y mettre un point d'arrêt et voir qui fait quoi) et aussi ce sera un point de synchronisation (si nécessaire) pour un accès multiple.

N'oubliez pas que les opérations d'E / S peuvent toujours échouer, voici un exemple courant:

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

Si quelqu'un supprime le fichier après File.Exists()mais avant File.Delete(), il jettera un IOExceptiondans un endroit où vous pourriez vous sentir mal en sécurité.

Chaque fois que c'est possible, appliquez un modèle de nouvelle tentative , et si vous utilisez FileSystemWatcher, envisagez de reporter l'action (car vous serez notifié, mais une application peut toujours travailler exclusivement avec ce fichier).

Scénarios avancés
Ce n'est pas toujours aussi simple, vous devrez peut-être partager l'accès avec quelqu'un d'autre. Si, par exemple, vous lisez du début et écrivez jusqu'à la fin, vous avez au moins deux options.

1) partager la même chose FileStreamavec les fonctions de synchronisation appropriées (car il n'est pas thread-safe ). Voir ceci et ces messages pour un exemple.

2) utilisez une FileShareénumération pour indiquer au système d'exploitation d'autoriser d'autres processus (ou d'autres parties de votre propre processus) à accéder au même fichier simultanément.

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

Dans cet exemple, j'ai montré comment ouvrir un fichier pour l'écriture et le partager pour la lecture; Veuillez noter que lors de la lecture et de l'écriture de chevauchements, il en résulte des données non définies ou invalides. C'est une situation qui doit être gérée lors de la lecture. Notez également que cela ne permet pas d'accéder au streamthread-safe, donc cet objet ne peut pas être partagé avec plusieurs threads à moins que l'accès ne soit synchronisé d'une manière ou d'une autre (voir les liens précédents). D'autres options de partage sont disponibles et ouvrent des scénarios plus complexes. Veuillez consulter MSDN pour plus de détails.

En général, N processus peuvent lire tous ensemble à partir du même fichier, mais un seul doit écrire.Dans un scénario contrôlé, vous pouvez même activer les écritures simultanées, mais cela ne peut pas être généralisé en quelques paragraphes de texte dans cette réponse.

Est-il possible de déverrouiller un fichier utilisé par un autre processus? Ce n'est pas toujours sûr et pas si facile mais oui, c'est possible .

Adriano Repetti
la source
Je ne sais pas ce qui ne va pas avec mon code, j'utilise des blocs, mais il y a toujours une erreur indiquant que le fichier est en cours d'utilisation lorsque j'essaie de le supprimer.
Jamshaid Kamran
Non, en fait, j'ai une commande de minuterie qui fait cela, à côté de la minuterie, si j'appelle à nouveau la fonction, elle lancera une exception. En gros, je décrypte un fichier dans un autre fichier texte, après cela, je supprime le fichier nouvellement créé, qui lève l'exception lors de la suppression!
Jamshaid Kamran
3
@ جمشیدکامران Pourquoi créer un fichier avec le contenu que vous avez dans votre code, puis le supprimer? Cela semble étrange de créer le fichier en premier lieu, alors. Puisque vous n'avez pas publié de code, nous ne savons pas ce que vous faites. Mais lorsque vous créez votre fichier, si vous le faites avec File.Create(path), vous devez ajouter .Close()la fin de celui-ci avant d'écrire dessus. Il y a des pièges comme ça, en plus des usinginstructions pour écrire les fichiers, puis pour les supprimer après eux. Vous devriez publier le code dans votre question pour savoir comment vous créez et supprimez votre fichier. Mais cela correspond probablement à quelque chose mentionné ci-dessus.
vapcguy
Mon code utilise Directory.SetCreationTimeUTC()mais il échoue lorsque l'Explorateur de fichiers est ouvert, affirmant que le répertoire est accédé par un autre processus. Comment dois-je gérer cette situation?
Kyle Delaney
1
@KyleDelaney Je dirais que vous devez attendre que le dossier soit fermé, si ce n'est pas quelques secondes, tout deviendra rapidement complexe (garder une file d'attente en arrière-plan avec des opérations en attente? Observateur du système de fichiers? Sondage?) publier une question avec plus de détails pour une réponse ad hoc
Adriano Repetti
29

L'utilisation de FileShare a résolu mon problème d'ouverture de fichier même s'il est ouvert par un autre processus.

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

J'ai rencontré un problème lors du téléchargement d'une image, je n'ai pas pu la supprimer et j'ai trouvé une solution. GL hf

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

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

//later...

File.Delete(filePath); //now works
Hudson
la source
2
Si vous supprimez un fichier, vous devez d'abord supprimer l'objet image.
shazia
1
Sympa, j'ai cherché cette solution. J'ai également eu un problème avec la fonction Image.FromFile.
le scion
1
@thescion :) np
Hudson
1
Cela a fonctionné à merveille pour moi et a résolu mon problème exact. Je voulais traiter un dossier de fichiers Tiff, les convertir en flux d'octets [] et les envoyer à un service, puis déplacer le dossier des fichiers Tiff vers un dossier d'archive «Traités». Image.FromFile place un verrou sur le fichier Tiff et ne le libère pas en temps opportun, donc lorsque je suis allé déplacer les fichiers Tiff et le dossier contenant, j'obtiendrais l'erreur "étant utilisé par un autre processus", car les verrous étaient toujours en place. Faire le .Release juste après avoir obtenu les octets du fichier Tiff a totalement résolu ce problème de fichier verrouillé.
Developer63
4

J'ai eu cette erreur parce que je faisais File.Move vers un chemin de fichier sans nom de fichier, je dois spécifier le chemin complet dans la destination.

l'amour en direct
la source
Et pas seulement sans nom de fichier. Un nom de fichier (de destination) illégal - dans mon cas "... \ fichier." - donnera cette même erreur stupide et vous pointera dans la mauvaise direction pendant une demi-journée!
Nick Westgate
3

L'erreur indique qu'un autre processus tente d'accéder au fichier. Peut-être que vous ou quelqu'un d'autre l'avez ouvert pendant que vous essayez de lui écrire. "Lire" ou "Copier" ne cause généralement pas cela, mais y écrire ou appeler delete le ferait.

Il y a quelques éléments de base pour éviter cela, comme d'autres réponses l'ont mentionné:

  1. En FileStreamopération, placez-le dans un usingbloc avec un FileShare.ReadWritemode d'accès.

    Par exemple:

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

    Notez que ce FileAccess.ReadWriten'est pas possible si vous utilisez FileMode.Append.

  2. J'ai rencontré ce problème lorsque j'utilisais un flux d'entrée pour faire un File.SaveAslorsque le fichier était en cours d'utilisation. Dans mon cas, j'ai trouvé que je n'avais pas du tout besoin de le sauvegarder dans le système de fichiers, donc j'ai fini par le supprimer, mais j'aurais probablement pu essayer de créer un FileStream dans une usinginstruction avec FileAccess.ReadWrite, un peu comme le code au dessus.

  3. Enregistrer vos données dans un fichier différent et revenir en arrière pour supprimer l'ancien lorsqu'il s'avère qu'il n'est plus utilisé, puis renommer celui qui a été enregistré avec succès au nom de l'original est une option. La façon dont vous testez le fichier en cours d'utilisation est effectuée via le

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

    ligne dans mon code ci-dessous, et pourrait être fait dans un service Windows, en boucle, si vous avez un fichier particulier que vous souhaitez regarder et supprimer régulièrement lorsque vous souhaitez le remplacer. Si vous n'avez pas toujours le même fichier, un fichier texte ou une table de base de données pourrait être mis à jour pour que le service vérifie toujours les noms de fichiers, puis effectue cette vérification des processus et effectue ensuite le processus tue et supprime, comme je le décris dans l'option suivante. Notez que vous aurez besoin d'un nom d'utilisateur et d'un mot de passe de compte disposant des privilèges d'administrateur sur l'ordinateur donné, bien sûr, pour effectuer la suppression et la fin des processus.

  4. Lorsque vous ne savez pas si un fichier sera en cours d'utilisation lorsque vous essayez de l'enregistrer, vous pouvez fermer tous les processus qui pourraient l'utiliser, comme Word, s'il s'agit d'un document Word, avant l'enregistrement.

    S'il est local, vous pouvez le faire:

    ProcessHandler.localProcessKill("winword.exe");

    S'il est distant, vous pouvez le faire:

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

    txtUserNameest sous la forme de DOMAIN\user.

  5. Disons que vous ne connaissez pas le nom du processus qui verrouille le fichier. Ensuite, vous pouvez faire ceci:

    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);
    }

    Notez qu'il filedoit s'agir du chemin UNC: \\computer\share\yourdoc.docxpour que le Processpuisse savoir sur quel ordinateur il se trouve et p.MachineNameêtre valide.

    Vous trouverez ci-dessous la classe à laquelle ces fonctions utilisent, ce qui nécessite l'ajout d'une référence System.Management. Le code a été écrit à l'origine par 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
la source
2

Comme d'autres réponses de ce fil l'ont souligné, pour résoudre cette erreur, vous devez inspecter attentivement le code pour comprendre où le fichier est verrouillé.

Dans mon cas, j'envoyais le fichier sous forme de pièce jointe à un e-mail avant d'effectuer l'opération de déplacement.

Le fichier a donc été verrouillé pendant quelques secondes jusqu'à ce que le client SMTP ait fini d'envoyer l'e-mail.

La solution que j'ai adoptée était de déplacer d'abord le fichier, puis d'envoyer l'e-mail. Cela a résolu le problème pour moi.

Une autre solution possible, comme indiqué précédemment par Hudson, aurait été de jeter l'objet après utilisation.

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
la source
Si un fichier est en cours d'utilisation File.Move()ne fonctionnera pas et donne la même erreur. Si vous ajoutez simplement un fichier à un e-mail, je ne pense pas que ce soit une erreur lors de son utilisation pendant l' Attachments.Add()opération car il ne s'agit que d'une opération de copie. Si c'est le cas pour une raison quelconque, vous pouvez le copier dans un répertoire Temp, joindre la copie et supprimer le fichier copié par la suite. Mais je ne pense pas, si l'OP veut modifier un fichier et l'utiliser, que ce genre de solution (dont vous n'avez pas montré le code, seule la partie jointe) fonctionnerait. .Dispose()est toujours une bonne idée, mais pas pertinente ici à moins que le fichier ne soit ouvert dans une opération antérieure.
vapcguy
1

J'ai eu le scénario suivant qui causait la même erreur:

  • Télécharger des fichiers sur le serveur
  • Ensuite, débarrassez-vous des anciens fichiers une fois qu'ils ont été téléchargés

La plupart des fichiers étaient de petite taille, cependant, quelques-uns étaient volumineux et toute tentative de suppression entraînait une erreur de fichier impossible d'accès .

Ce n’était pas facile à trouver, cependant, la solution était aussi simple que d’ attendre «que la tâche soit terminée»:

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

Mon code ci-dessous résout ce problème, mais je suggère que vous devez d'abord comprendre ce qui cause ce problème et essayer la solution que vous pouvez trouver en changeant le code

Je peux donner un autre moyen de résoudre ce problème, mais la meilleure solution est de vérifier votre structure de codage et d'essayer d'analyser ce qui fait que cela se produit, si vous ne trouvez aucune solution, vous pouvez utiliser ce code ci-dessous

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;
    }
 }
Cendre
la source
1
Quelques problèmes avec ce code: 1) si vous devez appeler, GC.*()vous avez probablement d'autres problèmes avec votre code. 2) Le message est localisé et fragile , utilisez plutôt HRESULT. 3) Vous voudrez peut-être dormir avec Task.Delay()(et dix secondes sont en quelque sorte excessives dans de nombreux cas). 4) Vous n'avez pas de condition de sortie: ce code pourrait se bloquer pour toujours. 5) Vous n'avez certainement pas besoin gotoici. 6) Attraper Exceptionest généralement une mauvaise idée, dans ce cas aussi parce que ... 6) Si autre chose se produit, vous avalez l'erreur.
Adriano Repetti
@AdrianoRepetti mon premier commentaire dit de ne pas utiliser ce code, essayez de trouver une autre solution, ce sera la dernière option et de toute façon si cette erreur se produit, le code s'arrête, mais si vous gérez cette erreur, le système attendra de libérer le fichier et après cela, il démarrera fonctionne et je ne rencontre pas d'autres problèmes avec GC. * tout en utilisant ce code.J'ai déjà un système de travail avec ce code, donc j'ai posté peut être utile pour quelqu'un.
Ash
Je dirais à ne pas utiliser ce code jamais ( à cause des points que je mentionnés ci - dessus) et je ne serais pas considérer ce travail dans un système de prod , mais qui est juste mon POV. N'hésitez pas à ne pas être d'accord!
Adriano Repetti
1) J'ai utilisé le service Windows où j'ai consommé ceci et j'ai utilisé GC. * Jusqu'à présent, je ne rencontre aucun problème avec cela 2) ouais HRESULT peut être une meilleure option en termes de norme de codage 3) Dépend de la situation, vous pouvez donner le temps que je viens de modifier à 5 secondes 4) de toute façon, il est préférable d'attendre le système pendant un certain temps pour libérer des ressources au lieu d'arrêter le système avec l'erreur 5) oui je suis d'accord avec vous, la gestion des exceptions n'est pas toujours une bonne idée, mais si votre extrait de code est petit et vous savez qu'ici je peux gérer l'exception, cette solution est une option pour vous.
Ash
Voir également: docs.microsoft.com/en-us/archive/blogs/ricom/… . Le SEUL (et j'insiste UNIQUEMENT) cas que j'avais besoin d'utiliser GC.Collect()a été celui de traiter certains objets COM.
Adriano Repetti