简体   繁体   English

意外地创建了多个流程

[英]Accidentally Creating More Than One Process

I am new to web programming (C# in Visual Web Developer) and my non-C programming skills are a little rusty too. 我是Web编程的新手(Visual Web Developer中的C#),我的非C编程技能也有些生锈。

I have created a table where some of the cells prompt for user input and, once the input is given, the input replaces the prompt. 我创建了一个表,其中一些单元格提示用户输入,一旦给出输入,输入将替换提示。 Thus the table can only be annotated by the first person to access the page. 因此,该表只能由第一人注释才能访问该页面。 Later the annotated page needs to be made available for others to view it so I need the page to load without the prompts after they have been done for the first time. 稍后,需要使带注释的页面可供其他人查看,因此我需要在第一次完成提示后加载页面而没有提示。 To do this I am (trying) to identify the user so that that person gets the editable page, all of the edits are saved to an xml file, and if another user runs the page the table settings get read back out of the xml file of edits. 为此,我(正在尝试)识别用户,以便该人获得可编辑页面,所有编辑都保存到xml文件中,如果另一个用户运行该页面,则从xml文件中读出表设置编辑。

I am having trouble consistently writing to the xml file. 我无法始终如一地写入xml文件。 Specifically I seem to sometimes create more than one process that is accessing the file and I throw a runtime exception when my code tries to update it. 具体来说,我有时似乎创建多个进程来访问文件,并且在我的代码尝试更新文件时抛出运行时异常。

Since I didn't want a new file being created on each page load I thought a static class was the way to go. 因为我不想在每次页面加载时都创建一个新文件,所以我认为应该使用静态类。 Here is the code: 这是代码:

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

and here is where I am calling the methods: 这是我调用方法的地方:

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

and finally there is a submit button to add the closing tag to the xml file: 最后是一个提交按钮,用于将结束标记添加到xml文件:

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

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

Sometimes everything works just fine -- although I seem to be producing malformed xml. 有时一切正常,尽管我似乎正在生成格式错误的xml。 But most of the time I get more than one process accessing the xml file. 但是大多数时候,我得到多个进程来访问xml文件。

Any advice is appreciated. 任何建议表示赞赏。

Regards. 问候。

Web programming means working in a multi-threaded environment. Web编程意味着在多线程环境中工作。

Each request from the browser to the Web server is a separate thread . 从浏览器到Web服务器的每个请求都是一个单独的线程

That's why sometimes your file can't be accessed, since it's possible that other request (say it thread ) had an exclusive lock on it. 这就是为什么有时无法访问您的文件的原因,因为其他请求(例如thread )可能对其具有排他锁。

Another point is using statement should be your friend, so replace: 另一点是using语句应该是您的朋友,所以替换:

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

... with: ...与:

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

This is an equivalent to a try-finally block and it calls Dispose method for any implementation of IDisposable . 这等效于try-finally块,它为IDisposable任何实现调用Dispose方法。 So in the case your block fails, it'll be always calling Dispose() . 因此,在您的块失败的情况下,它将始终调用Dispose()

And above comment it's fine to mention that if, during some operation in some thread something went wrong, a lock to the file will remain on it forever, until IIS application is stopped or application pool gets recycled. 在上面的注释中,最好提到的是,如果在某个线程中的某些操作过程中出现了问题,则对该文件的锁定将永远保留在该文件上,直到IIS应用程序停止或应用程序池被回收。

Summary: 摘要:

  1. In your case, more than a thread could be trying to write into the same file. 在您的情况下,可能有多个线程试图写入同一文件。
  2. Some error could leave some lock in affected files. 某些错误可能会在受影响的文件中留下一些锁定。

Solution: Never work with files in a Web application, there're better ways of saving data: databases - these solve a lot of problems in concurrent scenarios!! 解决方案: 永远不要在Web应用程序中使用文件,而是有更好的数据保存方式:数据库-这些解决了并发场景中的许多问题! - . -

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM