2009-11-28 29 views
20

tengo un simple XmlFileHelper clase de bloqueo de la siguiente manera:C# XML.load() archivo en el disco causando errores

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 
} 

La cuestión es que estoy recibiendo el siguiente error en la carga:

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

Esto ocurre cuando esta clase está siendo utilizada por dos instancias en ejecución de un componente que se ejecuta en paralelo, ambas tratando de cargar el archivo xml anterior, este es un comportamiento legítimo y requerido por la aplicación.

Solo quiero leer en el xml off disk una vez y liberar cualquier referencia al archivo en el disco y utilizar una representación en memoria desde ese punto en adelante.

Supongo que Load opera de manera que no tiene necesidad de bloquear el archivo, ¿cuál es la mejor manera de lograr el resultado deseado y evitar este problema?

Gracias

Respuesta

20

depende de lo que necesite del archivo,

Si necesita que sea threasdsafe que tendría que impliment un mutex para bloquear la carga entre instancia,

Si realmente no necesita una carga segura de subprocesos (es decir, el archivo nunca cambia), puede cargarlo a través de una secuencia de archivos y luego cargar el XmlDocument desde el transmitir

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

Estoy probando esto ahora, gracias – m3ntat

+0

Excelente esto hizo el truco! – m3ntat

-1

intento:

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

Si el archivo no es demasiado grande como para leer en la memoria a la vez:

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

Usted puede hacer esto

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

en lugar de

xmlDoc.Load(xmlFilePath); 
Cuestiones relacionadas