- PR -

複数アプリからの単一ファイルへの読み書き同期処理

1
投稿者投稿内容
TNEXT
会議室デビュー日: 2004/05/20
投稿数: 6
投稿日時: 2004-05-20 08:44
題目にありますように

アプリAとアプリBから
ファイルXに読み込み
書きこみを行います。

このときうまく同期を取りたいのですが、
良いやり方が浮かびません。

Mutexを使おうと思ったのですが、
片方のアプリはASP.NETなので
他方のアプリと同じ名前のMutexを
作成するときにアクセスエラーが出てしまいます。

どなたかアドバイスをお願いします。
甕星
ぬし
会議室デビュー日: 2003/03/07
投稿数: 1185
お住まい・勤務地: 湖の見える丘の上
投稿日時: 2004-05-20 12:28
引用:

アプリAとアプリBから
ファイルXに読み込み
書きこみを行います。

このときうまく同期を取りたいのですが、
良いやり方が浮かびません。



排他のためにファイルを使う方法が意外に有効です。ファイルを作成できたら、アクセス権取得成功。既にファイルがあるために作れなければ、既に他のプロセスがアクセスしていると判断できます。ファイルを使った排他制御はMS-Accessでも使っていますよね。

#「だったら最初からファイルXを開く時に排他かけたら?」と言う意見も有りますが。

引用:

Mutexを使おうと思ったのですが、
片方のアプリはASP.NETなので
他方のアプリと同じ名前のMutexを
作成するときにアクセスエラーが出てしまいます。



エラーコードぐらいは明記しよう。
サービスからだと権限の関係で名前つきMutexとかを開けなかったはずです。
APIを使って権限を取得すれば開けませんか?

_________________
甕星 <mikahosi@abox9.so-net.ne.jp>
http://blogs.msmvp.jp/mikahosi/
TNEXT
会議室デビュー日: 2004/05/20
投稿数: 6
投稿日時: 2004-05-21 05:31
もう少し詳しく教えていただけますか?

名前つきMutexを作成した場合のエラーは
以下のようなものです。

---------------------------------------------------
Access is denied.
Exception Details: System.ApplicationException: Access is denied.

Source Error:
Line 24: protected void Application_Start(Object sender, EventArgs e)
Line 25: {
Line 26: Mutex mutex = new Mutex(true, "XML_SHARE");
Line 27:
Line 28: Application.Add ("FileLock", mutex);

Source File: c:\inetpub\wwwroot\testreadclient\global.asax.cs Line: 26

Stack Trace:
[ApplicationException: Access is denied.]
System.Threading.Mutex.CreateMutexNative(Boolean initialState, String name, Boolean& createdNew) +0
System.Threading.Mutex..ctor(Boolean initiallyOwned, String name) +37
TestReadClient.Global.Application_Start(Object sender, EventArgs e) in c:\inetpub\wwwroot\testreadclient\global.asax.cs:26


Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2004-05-21 09:53
 同期を取りたい、ということなので、

アプリA    アプリB
 |書き込み
 |
 +終了通知−−−+
         |読み込み
         |書き込み
 +−−−終了通知+
 |読み込み
 ・
 ・
 ・

こういう風に、キャッチボールをするのかと思ったのですが、ただ単に「他方が読み書きしている間は読み書きしない」ということですか?

 それならミューテックスなんか使わなくても、共有ロックでOkですよ?う〜ん、上のキャッチボールも、やりようによっては共有ロックでOkだなぁ...
TNEXT
会議室デビュー日: 2004/05/20
投稿数: 6
投稿日時: 2004-05-22 00:51
そうです。
他方が書いているときは他方は読まずにまたは書かずに待つ。
ということです。

fs = new FileStream(TargetPath,FileMode.Open, FileAccess.Read,FileShare.ReadWrite);

このFileShareを書き込み時には、Noneに。
読み込み時にはReadWriteにしておけば
とりあえずデータを壊すことは無いということになりますね。

あとはアクセスエラーが出た場合
ファイルオープンを再施行させる
という感じでしょうか。
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2004-05-22 12:25
引用:

排他のためにファイルを使う方法が意外に有効です。



同意。

ファイルの場合、プロセス境界だけでなくマシン境界を越えたアクセスがあるかもしれないので、古典的な方法を採用するのが吉だと思います。

ちなみに、ファイルを握ったままでプロセスが死んでしまったような場合の対策ってどうしてます?


_________________
// 渋木宏明 (Hiroaki SHIBUKI)
// http://hidori.jp/
// Microsoft MVP for Visual C#
//
// @IT会議室 RSS 配信中: http://hidori.jp/rss/atmarkIT/
TNEXT
会議室デビュー日: 2004/05/20
投稿数: 6
投稿日時: 2004-05-23 00:30
usingまたはtry/catch/finallyで
エラー発生時にも確実なリソース開放を行います。

例:
using(fs = new FileStream(TargetPath,FileMode.Open, FileAccess.Read,FileShare.ReadWrite))
{
  //ファイルを使用する
}
1

スキルアップ/キャリアアップ(JOB@IT)