Crear accidentalmente más de un proceso

Soy nuevo en la programación web (C# en Visual Web Developer) y mis habilidades de programación que no son de C también están un poco oxidadas.

Creé una tabla donde algunas de las celdas solicitan la entrada del usuario y, una vez que se proporciona la entrada, la entrada reemplaza la solicitud. Por lo tanto, la tabla solo puede ser anotada por la primera persona que acceda a la página. Más tarde, la página anotada debe estar disponible para que otros la vean, por lo que necesito que la página se cargue sin las indicaciones después de que se hayan hecho por primera vez. Para hacer esto, estoy (intentando) identificar al usuario para que esa persona obtenga la página editable, todas las ediciones se guardan en un archivo xml, y si otro usuario ejecuta la página, la configuración de la tabla se vuelve a leer del archivo xml. de ediciones.

Tengo problemas para escribir constantemente en el archivo xml. Específicamente, parece que a veces creo más de un proceso que accede al archivo y lanzo una excepción de tiempo de ejecución cuando mi código intenta actualizarlo.

Como no quería que se creara un nuevo archivo en cada carga de página, pensé que una clase estática era el camino a seguir. Aquí está el código:

static class XMLReaderWriter
{
    static String fileLocation = "D:\\WebApp\\dashboard.xml";
    static XMLReaderWriter()
    {
        FileStream fs = File.Create(fileLocation);
        if (File.Exists(fileLocation))
        {
            // The opening tag
            writeToFile(fileLocation, "<Dashboard>\n");
        }
        else
        {
            Exception e = new Exception("Failed to create " + fileLocation);
            throw e;
        }
    }
    public static void writeXML(String xml)
    {
        if(File.Exists(fileLocation))
        {
            writeToFile(fileLocation, xml);
        }
        else
        {
            File.Create(fileLocation);
            writeToFile(fileLocation, xml);
        }
    }

    private static void writeToFile(String fileLocation, String xml)
    {
        StreamWriter sw = new StreamWriter(fileLocation, true);
        sw.WriteLine(xml);
        sw.Close();
        sw.Dispose();
    }

    public static string readXML(String trendID)
    {
        StringBuilder result = new StringBuilder("");
        if (File.Exists(fileLocation))
        {
            XDocument xDoc = XDocument.Load(fileLocation);
            var image = from id in xDoc.Descendants(trendID) select new
                        {
                            source = id.Attribute("image").Value
                        };
            foreach (var imageSource in image)
            {
                result.AppendLine(imageSource.source);
            }
        }
        return result.ToString();
    }

    public static void done()
    {
        // The closing tag
        writeToFile(fileLocation, "</Dashboard>");
    }
}

y aquí es donde estoy llamando a los métodos:

XMLReaderWriter.writeXML("\t<trend id=\"" + trendID +"\">\n\t\t" + innerHTML + "\" />\n\t</trend>");

y finalmente hay un botón de enviar para agregar la etiqueta de cierre al archivo xml:

<asp:Button runat="server" Text="Submit Changes" OnClick="Submit_Click" />

protected void Submit_Click(Object sender, EventArgs e)
{
    XMLReaderWriter.done();
}

A veces todo funciona bien, aunque parece que estoy produciendo xml mal formado. Pero la mayoría de las veces obtengo más de un proceso accediendo al archivo xml.

Cualquier consejo es apreciado.

Saludos.

preguntado el 12 de junio de 12 a las 22:06

1 Respuestas

La programación web significa trabajar en un entorno de subprocesos múltiples.

Cada solicitud del navegador al servidor web es una solicitud separada hilo.

Es por eso que a veces no se puede acceder a su archivo, ya que es posible que otra solicitud (dígalo hilo) tenía un bloqueo exclusivo.

Otro punto es usando declaración debería ser tu amigo, así que reemplaza:

StreamWriter sw = new StreamWriter(fileLocation, true);
sw.WriteLine(xml);
sw.Close();
sw.Dispose();

... con:

using(StreamWriter sw = new StreamWriter(fileLocation, true))
{
    sw.WriteLine(xml);
}

Esto es un equivalente a un probar-finalmente bloquea y llama Dispose método para cualquier implementación de IDisposable. Entonces, en caso de que su bloqueo falle, siempre estará llamando Dispose().

Y el comentario anterior está bien mencionar que si, durante alguna operación en algún subproceso, algo salió mal, un bloqueo para el archivo permanecerá en él para siempre, hasta que la aplicación IIS se detenga o el grupo de aplicaciones se recicle.

Resumen:

  1. En su caso, más de un hilo podría estar intentando escribir en el mismo archivo.
  2. Algún error podría dejar algún bloqueo en los archivos afectados.

Solución: Nunca trabaje con archivos en una aplicación web, hay mejores formas de guardar datos: bases de datos: ¡resuelven muchos problemas en escenarios concurrentes! -.

Respondido el 12 de junio de 12 a las 22:06

Ah gracias. No me di cuenta de que cada solicitud de página era un hilo separado. Eso lo explica todo. - Kevin

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.