1

「作成に費用がかかる」データを読み取ってキャッシュする、頻繁に使用される.Net 3.5アプリケーションがあります。ただし、キャッシュ ファイルの読み取りとキャッシュ ファイルへの書き込みの両方で多くのエラーが発生しています。StackOverflow フォーラムから得たアドバイスには次のようなものがあります。

  • を。「FileShare.Read」モードでファイルを読み取り、「FileShare.ReadWrite」モードでファイルに書き込みます。(システムが読み取り/書き込み操作を行っているときに、「FileAccess」モードを使用する必要があります。)
  • b. 各読み取りおよび書き込み操作の後に「GC.Collect」を使用します (各読み取り\書き込み操作の後にこれを行うことのパフォーマンスへの影響は何ですか)

これはファイルを読み書きする正しい方法ですか? お知らせ下さい。

private XmlDocument ReadFromFile(string siteID, Type StuffType)
{
   XmlDocument result = null;
   var fsPath = FileSystemPath(siteID, StuffType.Name);
   result = new XmlDocument();
   using (var streamReader = new StreamReader(fsPath))
   //using (var fileStream = new FileStream(fsPath, FileMode.Open, FileAccess.Read, FileShare.Read))
   {
      result.Load(streamReader);
   }
   //GC.Collect();                
   return result;
}

private readonly object thisObject = new object();
private void WriteToFile(string siteID, XmlDocument stuff, string fileName)
{
   var fsPath = FileSystemPath(siteID, fileName);
   lock (thisObject)
   {
      //using (var fileStream = new FileStream(fsPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
      using (var streamWriter = new StreamWriter(fsPath))
      {
         stuff.Save(streamWriter);
      }
      //GC.Collect();
    }
 }
4

3 に答える 3

7

リソースへのアクセスを同期したい場合は、コンテキストに応じていくつかのオプションがあります。いくつかの(一般的な)状況があります:

  1. シングルプロセス、シングルスレッド

    同期は必要ありません。

  2. 単一プロセス、複数スレッド

    lockまたはのような単純なロック機構を使用しReaderWriterLockSlimます。

  3. 複数のプロセス、単一のマシン

    (named) を使用しMutexます。Mutex はあまり高速ではありません。パフォーマンスの詳細については、下部をご覧ください。

  4. 複数のプロセス、複数のマシン

    今、それは興味を持ち始めています。.NET には、これに対する組み込みのソリューションはありません。私は2つの解決策を考えることができます:

    • 再試行方法: 内部に try-catch を含む while ループを作成します。彼に try スコープでのリソース操作を行わせます。成功した場合は、成功した結果を返します。失敗した場合は、数ミリ秒待ってからもう一度試してください...そしてもう一度...そしてもう一度。
    • 同期マスター: ネットワーク内の中央の場所で Web サービスを実行します。リソースへのアクセスを必要とするすべてのプロセスは、最初にサービスに許可を求める必要があります。リソースが「ロック」されている場合、サービスは待機し、その結果、プロセスが待機します。リソースが解放されるとすぐに、サービスに通知され、次のプロセスがリソースにアクセスできるようになります。

この場合
もちろん、この最後の解決策は一般的な解決策です。Ajit Goel の場合、ファイルを読み書きするための集中型サービスを作成するのと同じくらい簡単です。次に、iets ファイルを制御するファイルマスターが 1 つあります。

もう 1 つの解決策は、すべてのファイルを中央データベースに保存し、すべての同期を彼に任せることです。

パフォーマンス
パフォーマンスが問題になり始めた場合は、キャッシュの作成を試みることができます。

  1. メモリ内にキャッシュを作成できます (ただし、多数のファイルまたは大きなファイルがあると、メモリの問題になる可能性があります)。
  2. ローカル フォルダーにキャッシュを作成できます (プロセスごとに 1 つ)。中央の場所が変更されるとすぐに (日付を確認するだけです)、そのファイルを (Mutex ロックで) 自分のローカル フォルダーにコピーできます。そこから、読み取りアクセスと読み取り共有を使用して、ロックなしでファイルを何度も読み取ることができます。
于 2013-04-23T16:14:43.160 に答える
1

ReaderWriterLock とFileShare.ReadWriteの組み合わせが解決策だと思います。(注: リンク先のドキュメント ページでは、ReaderWriterLockSlimと呼ばれるより優れたバージョンを紹介しています。

各スレッドに FileShare.ReadWrite が必要なので、必要に応じてすべてアクセスできます。スレッドが読み取る必要があるときはいつでもAcquireReaderLock(ReleaseReaderLock読み取りが完了したときに) スレッドを取得します。

書きたいときは , 書き終わっUpgradeToWriterLockたらDowngradeFromWriterLock.

これにより、すべてのスレッドが常に読み取り専用でファイルにアクセスできるようになり、必要に応じて任意の 1 つのスレッドが書き込みアクセスを取得できるようになります。

それが役立つことを願っています!

于 2013-04-23T16:22:28.850 に答える