
実現したいこと
XMLデータが稀に途中から欠損してしまうので、そうならないようにしたい
前提
サーバープログラムを組んでいます
メインデータにはXMLで組んでいますが、稀に途中から欠損しておりバグとなっている
おそらく排他処理に問題があるのか、途中で書き込みエラ-となっている
サーバーはソケット通信で処理しており非同期で稼働させています
クライアントは20台程あります
クラインアントからのステータス更新を受け付けたら、xmlを書き換えるという作業をしています
ほぼ同時にクラインアントからの接続がくることもあります
発生している問題・エラーメッセージ
XML
1<Data1> 2 <Data2> 3 <key>165984</key> 4 <SlipStates>063282</SlipStates> 5 <Day>2023/05/24 11:00:00</Day> 6 7 </Data2> 8 <Data2> 9 <key>859521</key> 10 <SlipStates>063850</SlipStates> 11 <Day>2023/05/24 11:00:00</Day> 12 </Data2> 13 <Data2> 14 <key>654485</key> 15 <SlipStates>063850</SlipStates> 16 <Day>2023/05/24 11:00:00</Day> 17 </Data2> 18 <Data2> 19 <key>362114</key> 20 21 22------メモ帳とかで開くと上記の様に途中で切れていることがある 23当然ながら次読み込むときにReadXml でエラ-となる
該当のソースコード
C#
1コード //おそらく原因と思われるメソッド 2 public bool DateRewriting(string rewriteKey, string rewriteStr) 3 { 4 //時間 5 string strDate = DateTime.Now.ToString(); 6 7 //バックアップ処理(元ファイルをバックアップ用としてコピーして置く) 8 //\\date\main.xmlをリネームして\\date\mainBU.xmlとしてコピーして置く 9 10 using (DataSet set = new DataSet()) 11 { 12 bool flg = false; 13 int waitCount = 1; 14 15 while (!flg) 16 { 17 try 18 { 19 //ファイルロック //排他制御 20 using (FileStream fStream = new FileStream(@"\\date\main.xml", FileMode.Open, FileAccess.ReadWrite, FileShare.None)) 21 { 22 // XML の呼び出し 23 set.ReadXml(fStream); 24 25 //データの読み込み 26 using (DataTable table = set.Tables[0]) 27 { 28 //KeyIndex 書き込み対象のKeyのindexを取得 29 var index = table.Rows.IndexOf(table.AsEnumerable().Where(a => a.Field<string>(0) == rewriteKey).FirstOrDefault()); 30 31 //判定 32 if (index != -1) 33 { 34 //ステータス書き換え 35 set.Tables[0].Rows[index][1] = rewriteStr; 36 set.Tables[0].Rows[index][2] = strDate; 37 38 fStream.Seek(0, SeekOrigin.Begin); 39 fStream.SetLength(0); 40 41 //保存 42 set.WriteXml(fStream, XmlWriteMode.WriteSchema); 43 44 } 45 } 46 } 47 flg = true; 48 49 } 50 catch 51 { 52 //10秒は読込を待機させている ファイルロック 53 DelaySleep(500); 54 waitCount++; 55 56 if (waitCount == 20) 57 { 58 //10秒過ぎたらエラーとしている 59 // @"\\date\main.xml" はリネームしてエラー用LOGフォルダに―保存してから削除 60 // "date\mainBU.xml" をリネームして\\date\main.xmlにする 61 return false; 62 } 63 } 64 } 65 return true; 66 } 67 } 68
試したこと
自己学習でC#を実装しております。もしかしたら根本的に排他処理が間違っているのでしょうか?
FileShare.Noneしているので他のクラインアントからアクセスがあっても待機になるはずで2重書き込みみたいなことは起きないと考えています
XMLが途中から欠損してしまうことがあるのか教えて欲しいです
書き込み途中にエラーでWriteXmlまで到達していないということでしょうか?
処理の前にコピーを取ってエラーとなったら戻すやり方に変えてからは運用停止になることはなくなりましたが、バクのログを確認してみると稀に発生しています
ただ、上のコードだとバックアップもクラインアントからの接続の回数だけ行われておりますので負荷的にも大きいかと思います
タイミングによってはバックアップ処理も危ういと思っています
using (FileStream fStream = new FileStream(@"\date\main.xml", FileMode.Open, FileAccess.ReadWrite, FileShare.None))のところが良くないのでしょうか?
あまり的を得ていない質問かもしれませんがよろしくお願いします



回答1件
あなたの回答
tips
プレビュー