2

いくつかの質問を調査しましたが、見つけた答えはどれも役に立ちませんでした。この関数の目的は、xml ファイルを変更することです。元のファイルを読み取り、古いものと新しいものを新しいファイルに書き込みます。これはすべて完璧に機能します。問題は、完了したときに古いファイルを削除して新しいファイルを移動する必要があるときに発生します。

受け取ったエラーは、jnv_config.xml が別のプロセス (リーダー ファイル) によって使用されているというものです。

Close や Dispose を削除しても問題は解決しません。

using (XmlReader reader = XmlReader.Create("jnv_config.xml"))
using (XmlWriter writer = XmlWriter.Create("jnv_temp.xml"))
{
    writer.WriteStartDocument();
    while (reader.Read())
    {
      // Read the file, write to the other file - this part works perfectly.
      // No filestreams nor anything else is created in here.
    }
    writer.WriteEndElement();
    writer.WriteEndDocument();
    reader.Close();
    writer.Close();
    reader.Dispose();
    writer.Dispose();
}
// Delete the old file and copy the new one
File.Delete("jnv_config.xml");
//File.Move("jnv_temp.xml", "jnv_config.xml");

VS2012 (NET 4.5)、C#、標準 Windows フォーム プロジェクトを使用しています。

4

3 に答える 3

4

XmlReaderファイルがまだ開いているのはこれだと確信していますか? このコードを実行する前に、 Process Explorerを使用して、構成ファイルの開いているファイル ハンドルがないことを確認しましたか?

于 2013-02-06T00:12:08.420 に答える
0

私の経験では、多くのNTFSファイル処理関数(特にDELETE)はわずかに非同期です。スリープを追加しようとするか、名前を変更する前に少なくとも0.2秒待ちます。


それはうまくいかなかったので、代わりにスリープ/待機を前に置き、それが機能するまでゆっくりと増やすことをお勧めします。不当に長い期間(たとえば10秒)に達してもそれでも機能しない場合XmlReaderは、このコードに留まっている限り解放されないことが問題であるとかなり結論付けることができると思います。

その場合、GCを強制的に実行するなど、完全に破棄されるようにするために何かを行う必要がある場合があります。

于 2013-02-05T23:18:53.633 に答える
0

ファイルを削除する前に、ファイルの準備ができているかどうかを確認してください。大きなファイルで作業している場合、数秒間ループを介してコードを呼び出す可能性があります。

private void IsFileOpen(FileInfo file)
{
    FileStream stream = null;
    try {
        stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
    }
    catch (Exception ex) {

        if (ex is IOException && IsFileLocked(ex)) {
            // do something here, either close the file if you have a handle or as a last resort terminate the process - which could cause corruption and lose data
        }
    }
}

private static bool IsFileLocked(Exception exception)
{
    int errorCode = Marshal.GetHRForException(exception) & ((1 << 16) - 1);
    return errorCode == 32 || errorCode == 33;
}
于 2013-02-06T00:26:43.830 に答える