0

XmlWriterを使用すると、別のプロセスで使用されているというコードがクラッシュします。

    private void generateXml(Control receivedControl)
    {
        foreach (Control subCtrl in receivedControl.Controls)
        {
            using (XmlWriter writer = XmlWriter.Create("C:\\ui.xml"))
            {
                writer.WriteStartElement(subCtrl.Name);
                generateXml(subCtrl);
                writer.WriteEndElement();
            }
        }
    }

    private void button2_Click(object sender, EventArgs e)
    {
        foreach (Control c in this.Controls)
        {
            generateXml(c);
        }
    }

これが私がデバッグするエラーです:

追加情報:別のプロセスによって使用されているため、プロセスはファイル'C:\ui.xml'にアクセスできません。

編集:あなたのおかげで私は再帰を機能させることができましたが、それはxmlファイルの最後のオブジェクトのみを書き込みます、誰もが理由を知っていますか?更新されたコードは次のとおりです。

    private void generateXml(XmlWriter receivedWriter, Control receivedControl)
    {
        receivedWriter.WriteStartElement(receivedControl.Name);
        foreach (Control subCtrl in receivedControl.Controls)
        {
            generateXml(receivedWriter, subCtrl);
        }
        receivedWriter.WriteEndElement();
    }
    private void button2_Click(object sender, EventArgs e)
    {
        foreach (Control c in this.Controls)
        {
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;

            using(XmlWriter writer = XmlWriter.Create("c:\\ui.xml", settings))
            {
                writer.WriteStartDocument();
                writer.WriteStartElement("Form");
                generateXml(writer, c);
                writer.WriteEndElement();
                writer.WriteEndDocument();
            }
        }
    }
4

3 に答える 3

3

XmlWriter でアクセスするとファイルがロックされるため、それ以降の読み取り試行はエラーになります。

ライターをパラメーターとして渡すように関数を変更すると、コピーが 1 つになり、問題を回避できます。

private void generateXml(XmlWriter writer, Control receivedControl)
{
    foreach (Control subCtrl in receivedControl.Controls)
    {
            writer.WriteStartElement(subCtrl.Name);
            generateXml(writer, subCtrl);
            writer.WriteEndElement();
    }
}

private void button2_Click(object sender, EventArgs e)
{
    using (XmlWriter writer = XmlWriter.Create("C:\\ui.xml"))
    {
        writer.WriteStartDocument();
        writer.WriteStartElement(this.Name); // This is the document element
        foreach (Control c in this.Controls)
        {
            generateXml(writer, c);
        }
        writer.WriteEndDocument(); // Close any open tags
    }
}

上記はサンプルです - テストされていません。

編集:ルート要素を含めるように更新

于 2012-12-05T15:38:36.437 に答える
0

書き込みアクセスを共有するファイルを使用することもできます

        using (var f = new FileStream("C:\\ui.xml",      FileMode.Append,FileAccess.Write,FileShare.Write))
            {
                using (XmlWriter writer = XmlWriter.Create(f))                 
                {
                    writer.WriteStartElement(subCtrl.Name);
                    generateXml(subCtrl);
                    writer.WriteEndElement();
                }
            }
于 2012-12-05T15:47:18.913 に答える
0

XmlWriter writerこれは、一度に複数のインスタンスを開いているためです。

あなたがすべきことは、あなたのusingステートメントを再帰関数の外に置き、あなたのステートメントを渡すことXmlWriterです

using (XmlWriter writer = XmlWriter.Create("C:\\ui.xml"))
{
    generateXml(c, writer);
于 2012-12-05T15:38:26.623 に答える