0

非常に大きな XML ファイルを読み書きするためのWindows フォームアプリケーションを開発しようとしています。1) XML ファイルを書き込むためのボタンと、** および 2) XML ファイルを読み取るための 2 つのボタンがあります。[XML の書き込み] ボタンをクリックすると、winForm アプリケーションがハングします。XML ファイルへの書き込み中に他の操作を実行することはできませんが、同じ XML ファイルを読み書きしたいと考えています。

読書用

void btnReading_Click(object sender, EventArgs e)
{
    strXpathQuery = "/AppXmlLogWritter/LogData[substring(LogDateTime, 1, 8)  >='" +
                    dateTimePickerFromDate.Value.ToString("yyyyMMdd") +
                    "' and substring(LogDateTime, 1, 8)  <='" +
                    dateTimePickerToDate.Value.ToString("yyyyMMdd") +
                    "']";
    XmlElement objXmlRoot = null;
    XmlNodeList objxmlNodeList = objXmlRoot.SelectNodes(strXpathQuery);
}

void   BindData(objxmlNodeList);
{
    BindData(XmlNodeList objxmlNodeList)
    DataTable dataTable = new DataTable();
    dataTable = XmlNodeListToDataTable(objxmlNodeList, new string[] { "LogID", "LogDateTime"});

    lstViewInfo.View = View.Details;
    lstViewInfo.Clear();
    lstViewInfo.Columns.Add("LogID", Convert.ToInt32(lstViewInfo.Width * 0.20));
    lstViewInfo.Columns.Add("LogDateTime", Convert.ToInt32(lstViewInfo.Width * 0.20));
    ListViewItem objListViewitem = null;
    for (int i = 0; i < dataTable.Rows.Count; i++)
    {
        objListViewitem = new ListViewItem();
        objListViewitem.Text = dataTable.Rows[i]["LogID"].ToString();
        objListViewitem.SubItems.Add(dataTable.Rows[i]["LogDateTime"].ToString());
        lstViewInfo.Items.Add(objListViewitem);
    }
}

書き込み用

void button1_Click(object sender, EventArgs e)
{
    Mutex objMutex = new Mutex(false, @"Global\MySharedLog");
    XmlDocument xmlDoc = new XmlDocument();
    string currentDateTime = DateTime.Now.ToString("yyyyMMddHHmmss");
    XmlElement newelement = xmlDoc.CreateElement("LogData");
    XmlElement xmlLogID = xmlDoc.CreateElement("LogID");
    XmlElement xmlLogDateTime = xmlDoc.CreateElement("LogDateTime");

    int randomNumber = random.Next(9999);
    xmlLogID.InnerText = _logIDPrefix + currentDateTime + DateTime.UtcNow.Ticks + randomNumber;
    xmlLogDateTime.InnerText = currentDateTime;

    newelement.AppendChild(xmlLogID);
    newelement.AppendChild(xmlLogDateTime);

    try
    {
        objMutex.WaitOne();
        if (!File.Exists(_logFilePath))
        {
            File.WriteAllText(
              _logFilePath,
              "<?xml version='1.0' encoding='utf-8' standalone='yes'?>\r\n<AppXmlLogWritter><objMutex></objMutex></AppXmlLogWritter>");
        }

        using (FileStream fileStream = new FileStream(_logFilePath,
               FileMode.OpenOrCreate,
               FileAccess.ReadWrite,
               FileShare.ReadWrite))
        {
            xmlDoc.Load(fileStream);
            xmlDoc.DocumentElement.AppendChild(newelement);
            fileStream.SetLength(0);
            xmlDoc.Save(fileStream);
        }
    }
    finally
    {
        objMutex.ReleaseMutex();
    }
 }
4

4 に答える 4

2

別のスレッドに移動するのではなく、UI スレッドを使用してすべての作業を行うため、アプリケーションがハングします。

これには(操作として)時間がかかり、UI スレッドがビジーである限り、再描画、移動、マウスへの反応などの重要なメッセージを処理できません。

ハンドラーの.NET 4.5非同期メソッドのバックグラウンドワーカーは、すぐにそれを修正します。

于 2013-01-25T06:29:44.183 に答える
0

はい、作成に使用するメソッド XmlNodeListToDataTable() がxmlノード全体をバインドするためです。行を作成して列を追加し、それぞれの列に値を追加します。XML ファイルのファイル サイズが 1 GB であるとします。次に、XML ノードが大量にあるため、XML データ全体をデータテーブルにバインドするには多くの時間がかかります。

したがって、データセット内の XML ファイルを取得して表示するためのより良い方法は、データセット内のデータテーブルをトラバースすることです。具体的には、XML をデータテーブルにバインドするよりも時間がかかりません。

于 2013-01-25T06:51:44.527 に答える
0

ファイルを開こうとしているため、アプリケーションがハングしています。「XmlNodeListToDataTable」で使用しているメソッドは何ですか? MSXML? その場合は、 XPathを使用してみてください。より高速で、XML をより速くロードできます。また、「XmlNodeListToDataTable」を別のスレッドで実行して、必要に応じて GUI を引き続き応答できるようにすることもできます。

于 2013-01-25T06:15:27.450 に答える
0

箱から出して... Xsd2Codeを試すこともできます。私たちのプロジェクトでも使用しているオープンソースのツールです。保守が容易で、管理が容易です。大きな XML ファイルを処理する場合でも。

そして、Windows フォームがハングすることに関しては、まずXPathを使用すると、操作が高速になる可能性があります。吊るしに関しては、新スレでの運用が唯一の望みです。XML ファイルを作成するときと同様に、メイン ウィンドウのスレッドはビジーです。スレッド化のスケルトン コードは次のようになります。

private void WriteXML_Click(object sender, EventArgs e)
{
    Thread t = new Thread(new ThreadStart(WriteXMLFile));
    t.Start();
}

private void WriteXMLFile()
{
    // Write an XML file
}

このコードは、スレッドを使用するための単なるサンプル コードです。これらの投稿投稿も役立ちます。

于 2013-01-25T07:27:34.317 に答える