- naomix
- ベテラン
- 会議室デビュー日: 2003/02/01
- 投稿数: 56
|
投稿日時: 2003-12-25 16:13
WEBアプリケーションでテキストファイルに実行履歴を出力したくて、
方法を考えたのですが、知り合いに識者がいなくて、
これでいいものかどうか判断しかねています。
ご意見をちょうだいできればありがたいです。
これは変だとか、ここは不要だとか、こっちの方がスマートだとか
何かアドバイスがあればお願いします。
実は
new Mutex(false, "LogFileLock")
の第1パラメータと
mutex.WaitOne(new TimeSpan(0,0,5), false)
の第2パラメータの意味合いを
よく理解しておりません。
falseにしてやってみたら、意図したとおりに動作したような気がしたので
falseにしているだけです。
これらのパラメータの妥当性が気になるところです。
Global.asaxの処理
| コード: |
| //Mutexを作り、Applicationオブジェクトに格納します。
protected void Application_Start(Object sender, EventArgs e)
{
Mutex mutex = new Mutex(false, "LogFileLock");
Application.Add ("LogFileLock", mutex);
}
//MutexをCloseします。
protected void Application_End(Object sender, EventArgs e)
{
Mutex mutex = (Mutex) Application["LogFileLock"];
mutex.Close();
}
|
ファイル出力の処理
| コード: |
| DateTime NowDt = DateTime.Now;//現在時刻取得
//ファイル名に本日の日付を含めます
string logFileName = "D:\\LogFile\\" + "WEB" + NowDt.ToString("yyyyMMdd") + ".log";
//ApplicationオブジェクトからMutexを取り出します。
Mutex mutex = (Mutex) Application["LogFileLock"];
if(mutex.WaitOne(new TimeSpan(0,0,5), false)) //5秒待ってダメなら何もしない
{
try
{
using (StreamWriter writer = new StreamWriter(logFileName, true, Encoding.GetEncoding("Shift_JIS")))
{
writer.WriteLine(String.Format("{0:HH:mm:ss}, {1}", NowDt, "処理内容"));
}
}
finally
{
mutex.ReleaseMutex();
}
}
|
|
- naomix
- ベテラン
- 会議室デビュー日: 2003/02/01
- 投稿数: 56
|
投稿日時: 2003-12-25 22:16
Mutexを使わなくてもできるのではないかと
さらに考えてみました。
最初のコードとの違いは、
Global.asaxのApplication_Startで
ただのObjectを作って、Applicationオブジェクトに格納します。
ファイル出力の処理では、
Applicationオブジェクトから
さっきのObjectを取り出して、
Monitor.TryEnterの第一パラメータとします。
一応予定通り動作しましたが、これでいいのだろうか。
私は、WEBアプリケーションのアプリケーションドメインとかスレッドが
どうなっているのかよくわかっていません。
Global.asaxの処理
| コード: |
| protected void Application_Start(Object sender, EventArgs e)
{
Object obj = new Object();
Application.Add ("LogFileLock", obj);
}
|
ファイル出力の処理
| コード: |
| DateTime NowDt = DateTime.Now;//現在時刻取得
//ファイル名に本日の日付を含めます
string logFileName = "D:\\LogFile\\" + "WEB" + NowDt.ToString("yyyyMMdd") + ".log";
Object obj = Application["LogFileLock"];
if(Monitor.TryEnter (obj, new TimeSpan(0,0,5))) //5秒待ってダメなら何もしない
{
try
{
using (StreamWriter writer = new StreamWriter(logFileName, true, Encoding.GetEncoding("Shift_JIS")))
{
writer.WriteLine(String.Format("{0:HH:mm:ss}, {1}", NowDt, "処理内容"));
}
}
finally
{
Monitor.Exit(obj);
}
}
|
|
- naomix
- ベテラン
- 会議室デビュー日: 2003/02/01
- 投稿数: 56
|
投稿日時: 2003-12-26 01:17
何がしたいのかというと、要するに
ファイルの排他制御をしたいんです。
|
- 小野@どっとねっとふぁん
- ぬし
- 会議室デビュー日: 2001/10/30
- 投稿数: 402
|
投稿日時: 2003-12-26 12:38
| 引用: |
|
naomixさんの書き込み (2003-12-26 01:17) より:
何がしたいのかというと、要するに
ファイルの排他制御をしたいんです。
|
Application.Lock とかじゃいけないのかな。
|
- naomix
- ベテラン
- 会議室デビュー日: 2003/02/01
- 投稿数: 56
|
投稿日時: 2003-12-26 15:02
小野@EAC様。どうもありがとうございます。
ちょうどMonitorやMutexを用いたスレッド同期の勉強をしていたところだったので、
そればっかりに気を取られて、
Application.Lock()のことはまったく思いつきませんでした。
一部変えつつ、やってみました。
| コード: |
| string folder = (string) Application["WebLog"];//Applicationステートに格納しておいたログファイルのフォルダを取り出す。
DateTime NowDt = DateTime.Now;//現在時刻取得
string logFileName = folder + "WEB" + NowDt.ToString("yyyyMMdd") + ".log";
Application.Lock();
using (StreamWriter writer = new StreamWriter(logFileName, true, Encoding.GetEncoding("Shift_JIS")))
{
writer.WriteLine(String.Format("{0:HH:mm:ss}, {1}: {2}", NowDt, Request.Url.AbsolutePath, "TestA その1"));
Thread.Sleep(10000);//10秒間一時停止
writer.WriteLine(String.Format("{0:HH:mm:ss}, {1}: {2}", DateTime.Now, Request.Url.AbsolutePath, "TestA その2"));
}
Application.UnLock();
|
Global.asaxの処理も不要ですし、非常にシンプルでわかりやすくなりました。
無用にアプリケーションステート全体にロックを掛けてしまう点を
除けばこれも良いですね。
アプリケーションステートを使っていないシステムなら有効だと思うのですが、
Application.Lock()って
更新はもちろん読み込みにもロックが掛かりますよね。
他にアプリケーションステート使ってたら
パフォーマンスが低下してしまいます。
待ち合わせのタイムアウトを設定できないのも、残念です。
|
- 小野@どっとねっとふぁん
- ぬし
- 会議室デビュー日: 2001/10/30
- 投稿数: 402
|
投稿日時: 2003-12-26 19:00
ログをちょっと書き込んで終了、というレベルなら
実用になるかと思うんですけどね。
まぁ、間に重い処理をいれたい、ということなら
これじゃだめですね。
で、lockステートメントはどうだったっけな。
|
- なちゃ
- ぬし
- 会議室デビュー日: 2003/06/11
- 投稿数: 872
|
投稿日時: 2003-12-27 01:26
ログ出力するクラスに静的なメンバを入れて、lock もしくは Monitor を使うとかやってしまいそうです。
ログ出力の同期くらいにはあまり Application は使いたくなかったり…
あるいは、出力ファイルのフルパスをハッシュした値を元に Mutex を使ってみたりとか…
|
- naomix
- ベテラン
- 会議室デビュー日: 2003/02/01
- 投稿数: 56
|
投稿日時: 2003-12-27 15:59
小野@EAC様。ありがとうございます。
こちらの要件としても
ログをちょっと書き込むだけなのですが、
やはり無用にアプリケーションステート全体にロックを掛けてしまうのが
どうしても気になります。
lockステートメントは
Monitor.EnterとMonitor.Exitの組み合わせと同じです。
|