2009-11-28 13 views
20

Ho una semplice XmlFileHelper classe di bloccaggio come segue:C# XML.load() file sul errori del disco causando

public class XmlFileHelper 
{ 
    #region Private Members 

    private XmlDocument xmlDoc = new XmlDocument(); 
    private string xmlFilePath; 

    #endregion 

    #region Constructor 

    public XmlFileHelper(string xmlFilePath) 
    { 
     this.xmlFilePath = xmlFilePath; 
     xmlDoc.Load(xmlFilePath); 
    } 

    #endregion 

    #region Public Methods 

    public XmlNode SelectSingleNode(string xPathQuery) 
    { 
     return xmlDoc.SelectSingleNode(xPathQuery); 
    } 

    public string GetAttributeValueByName(XmlNode node, string attributeName) 
    { 
     return node.Attributes.GetNamedItem(attributeName).Value; 
    } 

    #endregion 

    #region Public Properties 

    public string XmlFilePath 
    { 
     get 
     { 
      return xmlFilePath; 
     } 
    } 

    #endregion 
} 

Il problema è che sto ottenendo il seguente errore sul carico:

System.IO.IOException: The process cannot access the file ''C:\CvarUAT\ReportWriterSettings.xml'' **because it is being used by another process** 

questo si verifica quando questa classe è utilizzata da due istanze in esecuzione di un componente in esecuzione in parallelo sia nel tentativo di caricare il file xml sopra, questo è un comportamento legittimo e richiesto dall'applicazione.

Voglio solo leggere il disco fuori xml una volta e rilasciare qualsiasi riferimento al file su disco e utilizzare una rappresentazione in memoria da quel punto in avanti.

Avrei pensato che Load funzionasse in modo readonly e non avrebbe bisogno di bloccare il file, qual è il modo migliore per ottenere il risultato desiderato e aggirare questo problema?

Grazie

risposta

20

dipende da ciò che è necessario dal file,

Se avete bisogno di essere threasdsafe si avrebbe bisogno di impliment un mutex per bloccare il carico tra istanza,

Se non si ha realmente bisogno del caricamento sicuro dei thread (ovvero il file non cambia mai), è possibile caricarlo tramite un flusso di file, quindi caricare XmlDocument dal streaming

  FileStream xmlFile = new FileStream(xmlFilePath, FileMode.Open, 
FileAccess.Read, FileShare.Read); 
      xmlDoc.Load(xmlFile); 
+0

Sto provando questo ora, grazie – m3ntat

+0

Eccellente questo ha fatto il trucco! – m3ntat

-1

prova:

xml.Load(
     new StreamReader(
      new FileStream(
        path, 
        FileMode.Open, 
        FileAccess.Read, 
        FileShare.Read) 
      ) 
     ); 
0

Se il file non è troppo grande per leggere in memoria tutti in una volta:

xml.Load(new MemoryStream(File.ReadAllBytes(path))); 
34

È possibile farlo

using (Stream s = File.OpenRead(xmlFilePath)) 
{ 
    xmlDoc.Load(s); 
} 

invece di

xmlDoc.Load(xmlFilePath); 
Problemi correlati