6

asp.net Web アプリケーションで、ファイルに書き込みたい。この関数は、最初にデータベースからデータを取得し、次にフラット ファイルに書き出します。

書き込みが1回だけ発生するようにするにはどうすればよいですか。書き込みが発生すると、書き込みが行われたため、ファイルに書き込みたいと思われる他のスレッドは書き込みを行いません。

この書き込みは、たとえば 15 分以内に行われていない場合にのみ行いたいと考えています。

lock キーワードがあることは知っているので、すべてをロックでラップしてから、15 分以上で更新されたかどうかを確認する必要がありますか、それともその逆ですか?

アップデート

ワークフロー:

これは Web アプリケーションであるため、複数のインスタンスは特定の Web ページを表示する人々になります。ビルドイン キャッシュ システムを使用することもできますが、asp.net がリサイクルする場合、キャッシュを再構築するのに費用がかかるため、フラット ファイルに書き出すだけです。私の他のオプションは、Windows サービスを作成することですが、それは私が望むより多くの管理作業です。

4

7 に答える 7

2

書き込みコードを同期して共有オブジェクトをロックし、1 つのスレッドのみがブロック内に入るようにします。他の人は、現在のものが終了するまで待ちます。

lock(this)
{
  // perform the write.
}

更新:共有オブジェクトがあると仮定しました。これらが同じマシン上の異なるプロセスである場合は、名前付きミューテックスのようなものが必要になります。例についてはこちらをご覧ください

于 2008-09-18T15:30:33.963 に答える
1

インスタンス全体ではなく、オブジェクト変数をロックするほうがよいのではないでしょうか?

于 2008-09-18T15:35:20.613 に答える
1

ファイルに書き込むファイル I/O 操作は、ファイルを自動的にロックします。ファイルが (書き込みを試行して) ロックされているかどうかを確認し、ロックされていないかどうかを確認します。書き込みを行う前に、ファイルのタイムスタンプを確認し、15 分以上かどうかを確認してください。

Windowsなどによってロックされていないと、ファイルに書き込むことはできません。

あとは、msdn を使用して上記を実行する方法を調べるだけです (申し訳ありませんが、すべて調べるのは面倒ですし、C# のクラスもよく覚えていません)。:)

于 2008-09-18T15:58:23.540 に答える
0
   // try enter will return false if another thread owns the lock
   if (Monitor.TryEnter(lockObj))
   {
      try
      {
         // check last write time here, return if too soon; otherwise, write
      }
      finally
      {
         Monitor.Exit(lockobj);
      }
   }
于 2008-09-18T15:38:32.633 に答える
0

皆さんはミューテックスを検討する必要があります。複数のスレッドとプロセス間で同期できます。

于 2011-03-25T10:19:25.030 に答える
0

私は、.NET のロックがさまざまなプロセスに適用できるとは確信していません。さらに、lock(this) は、「this」の同じインスタンスでメソッドを実行している他のスレッドのみを除外します。そのため、同じプロセス内の他のスレッドであっても、異なるインスタンスで一度に実行できます。

すべてのプロセスが同じマシンで実行されていると仮定すると、ファイルのロックはそれを行うはずです。

別のマシンを使用している場合、マイレージは異なる場合があります-win32はネットワーク経由で機能するファイルロックを持っていると主張していますが、歴史的にそれに依存するアプリケーション(MSAccessを考えてください)はとにかくファイルの破損に問題があります.

于 2008-09-18T15:35:26.497 に答える
0

ファイル システム ロックを使用する

他の人が示唆したように、.NET ロックは、この状況では使用が制限されます。コードは次のとおりです。

FileInfo fi = new FileInfo(path);
if (fi.Exists
    && (DateTime.UtcNow - fi.LastWriteTimeUtc < TimeSpan.FromMinutes(15)) {
  // file is fresh
  return;
}

FileStream fs;
try {
  fs = new FileStream(
    path, FileMode.Create, FileAccess.Write, FileShare.Read);
} catch (IOException) {
  // file is locked
  return;
}

using (fs) {
  // write to file
}

これは、スレッドプロセス全体で機能します。

于 2008-10-04T16:03:30.723 に答える