2

ファイルシステムから XML をロードし、テキストボックスに入力する単純なページがあります。これらは更新および保存できます。シリアライズとデシリアライズには、次のメソッドを使用しています。

private static readonly object FormDataLock = new object();

public static FormData getFormData(string filename)
{
    FormData fd;
    lock (FormDataLock)
    {
        XmlSerializer x = new XmlSerializer(typeof(FormData));
        using (Stream s = new FileStream(filename, FileMode.Open, FileAccess.Read))
        {
            return (FormData)x.Deserialize(s);
        }
    }
}

public void saveFormData(string filename)
{
    lock (FormDataLock)
    {
        XmlSerializer x = new XmlSerializer(typeof(FormData));
        using (Stream s = new FileStream(filename, FileMode.Create, FileAccess.Write))
        {
            x.Serialize(s, this);
        }
    }
}

しかし、問題は、私が時々 gettig していることです (PageLoad の後で [保存] ボタンをクリックするのが速すぎることに気づいたように) IOException:

IOException: The process cannot access the file ".." because it is being used by another process. 

ミューテックスでブロックをロックしようとしましたが、まだ正しく機能していません。ページ フォームは非常にシンプルですが、その上で UpdatePanel を使用しています (重要ですか?)。

ページが読み込まれ、最初の保存リクエストが正常に行われると、ボタンをできるだけ早くクリックでき、すべてが正常です (例外はありません)。

4

2 に答える 2

2

XmlSerialization は、一時ディレクトリでシリアル化しようとしているクラスに固有の新しい dll をオンザフライで作成します。これらは、パフォーマンスを向上させるために作成されます。http://msdn.microsoft.com/en-us/library/swxzdhc0.aspxを参照してください。

GC.Collect などを呼び出す代わりに、シリアライザーをクラスの静的フィールドとして作成してみてください。これにより、パフォーマンスが向上し、一度しか作成されないため、問題が解決する可能性があります。

このコードは、スレッド セーフな方法で単一の xmlserializer を作成します。これに [ThreadStatic] 属性を追加しないでください。これにより、コードがスレッドごとに 1 回実行され、スレッドが再び安全ではなくなります。

private static readonly XmlSerializer xmlSerializer = 
    new XmlSerializer(typeof(FormData));
于 2012-12-17T00:04:09.573 に答える
0

私も同様の問題を抱えていましたが、これがあなたにも役立つことを願っています。問題は、2回目のクリックの前にガベージコレクターがクリーンアップされなかったため、手動で呼び出す必要があることでした。生きる前にGCに電話してみてくださいusing

GC.Collect();
GC.WaitForPendingFinalizers();
于 2012-12-16T23:47:41.130 に答える