0

我是 Web 编程新手(Visual Web Developer 中的 C#),我的非 C 编程技能也有点生疏。

我创建了一个表格,其中一些单元格提示用户输入,一旦给出输入,输入就会替换提示。因此,表格只能由第一个访问该页面的人注释。稍后需要将带注释的页面提供给其他人查看,所以我需要在第一次完成后加载页面而没有提示。为此,我(尝试)识别用户,以便该人获得可编辑页面,所有编辑都保存到 xml 文件中,如果另一个用户运行该页面,则表设置会从 xml 文件中读回的编辑。

我无法始终写入 xml 文件。具体来说,我有时似乎会创建多个访问文件的进程,并且当我的代码尝试更新它时会引发运行时异常。

因为我不想在每次页面加载时创建一个新文件,所以我认为静态类是要走的路。这是代码:

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

这是我调用方法的地方:

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

最后有一个提交按钮,可以将结束标记添加到 xml 文件中:

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

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

有时一切正常——尽管我似乎生成了格式错误的 xml。但大多数时候,我得到多个访问 xml 文件的进程。

任何建议表示赞赏。

问候。

4

1 回答 1

1

Web 编程意味着在多线程环境中工作。

从浏览器到 Web 服务器的每个请求都是一个单独的线程

这就是为什么有时无法访问您的文件的原因,因为其他请求(例如thread)可能对其具有排他锁。

还有一点是using 语句应该是你的朋友,所以替换:

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

... 和:

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

这相当于一个try-finally块,它调用Dispose任何实现的方法IDisposable。因此,如果您的块失败,它将始终调用Dispose().

在上面的评论中,可以提一下,如果在某个线程中的某些操作期间出现问题,文件的锁定将永远保留在其上,直到 IIS 应用程序停止或应用程序池被回收。

概括:

  1. 在您的情况下,可能不止一个线程正在尝试写入同一个文件。
  2. 一些错误可能会在受影响的文件中留下一些锁定。

解决方案:永远不要在 Web 应用程序中处理文件,有更好的方法来保存数据:数据库 - 这些解决了并发场景中的很多问题!-

于 2012-06-12T21:28:28.900 回答