質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Q&A

解決済

1回答

829閲覧

C# 複数のPCで1つのファイルを監視、IOする場合

退会済みユーザー

退会済みユーザー

総合スコア0

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

0グッド

0クリップ

投稿2018/11/21 07:24

編集2018/11/21 07:56

C#、visual studio2017で開発しています。

複数のPCで1つのファイルを監視、IOができるシステムを作りたいと考えています。
ファイルの監視はFileSystemWatcherクラスを使用しています。

「IOができる」とうことで1つのファイルに対して複数のPCから書込みをしたり、読込みをしたりしています。

・書込みのタイミングはユーザーの任意のタイミング
・読込みのタイミングはファイルが変更された時点でFileSystemWatcherイベントが発生し、自動的に読み込む。

この2つの条件で開発を進めているのですが、問題点がいくつかあります。

1.書込みのタイミングが重なったらエラーが発生してしまう。

2.FileSystemWatcherのイベント発生タイミングは全て同じなので読込みが重なり、エラーが発生してしまう。
(それぞれのPCで1つのファイル変更を監視しているので、ファイルが変更された時点でイベントが発生し、それぞれのPCから1つのファイルを読み込もうとするため、エラーが発生する。)

この問題を解決するために以下の対策をしました。

C#

1public void 読み書きメソッド(){ 2 try{ 3 読み書きの処理 4 }catch{ 5 読み書きメソッド() 6 } 7} 8

良くない処理だとは思うのですが[try catch]で処理が完了するまで永遠に処理を繰り返すようにしています。
この方法で一応エラーは出なくなったのですが、デバッグをすると必ず、catchをしています。

このままでは気持ちが悪いのでIOについて少し調べました。

[FileStream]クラスを使用することで読み書きどちらも可能にすることができる?みたいなのですが、
読込み時に書き込み処理をしているとNullが入ってしまうバグが発生してしまいました。

結局読み込みと書き込みは一緒にすることができなさそうなのですが、
「複数のユーザーからの書き込み」と「複数のFileSystemWatcherイベントからの読込み」
を制御することは可能なのでしょうか?
また、現在はFile.クラスでストリームを使わずに処理をしています。(読み込む情報量がとても少ないため)
この場合でもStreamクラスを使うべきでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2018/11/21 07:28

読み書きするプロセスを一つだけにし、他のプロセスは監視プロセスと通信するようにすればいいと思います。
退会済みユーザー

退会済みユーザー

2018/11/21 07:41

ご回答ありがとうございます。すみません、プロセスという言葉にピンと来ていないのですが、読み書きをするプロセスを1つにする。ということは読み書きをするPCを1つにするということでしょうか?
papinianus

2018/11/21 07:51 編集

「FileSystemWatcherのイベント発生タイミングは全て同じなので読込みが重なり、エラーが発生してしまう」というのはどういう事態ですか?噛み砕いていただけませんか?
退会済みユーザー

退会済みユーザー

2018/11/21 07:57

すみません。質問の部分を修正しました。
YAmaGNZ

2018/11/21 08:16

「読込みが重なり、エラーが発生してしまう」に関しては、エラーメッセージを書いたほうがよろしいかと思います。
papinianus

2018/11/21 08:33

要件からして、Zuishin様が書いておられるようなサービス的な立場のプロセスが必要だと思います。ピンポイントで読み取りイベントの衝突の回避だけをジャストアイデアで語ると、CSMA/CAの送信クライアントのようにランダムな待ちを入れるとかも思いつきましたが実用的ではないです。
guest

回答1

0

ベストアンサー

どのようなシステムかは存じませんが、書き込みに関しては、ユーザートリガーとのことなので、
競合した場合、ユーザーに通知し再度トリガーを起こしてもらうのはどうでしょう?

また、ファイルの読み書きが同時にとのことですが、データ的にはどうなのでしょうか?
ファイルへの書き込み中にReadで得られるデータは必要なのでしょうか?

現状のリトライ処理ですが、再起呼び出しとなっている為、ファイルのロックが続いた場合やネットワーク障害が発生した場合など長時間例外が発生する状態となる場合、System.StackOverflowExceptionが発生する可能性があるかと思います。
永久ループにし、成功時に抜けるほうがよろしいかと思います。
(さらにタイムアウトなどの監視をもうけるべきだとは思います)

投稿2018/11/21 07:50

YAmaGNZ

総合スコア10222

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/11/21 08:00

ご回答ありがとうございます。 ユーザートリガーですが、再度トリガーを起こしてもらうことはユーザーの都合上不可能です。。。 確かに、リトライするにも永久ループで成功時に抜けるほうが良さそうですね。 ユーザーからのトリガーを絶対に反映させないといけないのでとても参考になりました。
YAmaGNZ

2018/11/21 08:05

トリガーを起こしてもらうというのは、例えば、「更新」ボタンを押した時に今回の処理が行われる場合 競合した時に、「保存中にエラーが発生しました。再度更新してください。」とダイアログで通知し、ユーザーに再度「更新」ボタンを押してもらうということです。 どのみち、Writeの競合以外のエラーに関してはユーザーに通知することになるのでしょうから、競合時も通知すればいいのではないでしょうか?
退会済みユーザー

退会済みユーザー

2018/11/22 00:01

そうですね。その方向性で作成しユーザーにも了承していただけるように話してみようと思います。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問