私の質問は、私があまりできない多くのレガシーコードを継承することに基づいています。基本的に、私はデータのブロックを生成するデバイスを持っています。そのデータのブロックを作成するためにデバイスを呼び出すライブラリは、何らかの理由で私は完全には理解しておらず、変更したくても変更できず、そのデータのブロックをディスクに書き込みます。
この書き込みは瞬時ではありませんが、最大90秒かかる場合があります。そのとき、ユーザーは生成されているデータの部分的なビューを取得したいので、他のライブラリがディスクに書き込んでいるデータを読み取るコンシューマースレッドが必要です。
このレガシーコードに触れる前に、私が完全に制御するコードを使用して問題を模倣したいと思います。私はC#を使用していますが、これは表面上、必要な機能が多数提供されているためです。
プロデューサークラスでは、ランダムなデータブロックを作成する次のコードがあります。
FileStream theFS = new FileStream(this.ScannerRawFileName,
FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read);
//note that I need to be able to read this elsewhere...
BinaryWriter theBinaryWriter = new BinaryWriter(theFS);
int y, x;
for (y = 0; y < imheight; y++){
ushort[] theData= new ushort[imwidth];
for(x = 0; x < imwidth;x++){
theData[x] = (ushort)(2*y+4*x);
}
byte[] theNewArray = new byte[imwidth * 2];
Buffer.BlockCopy(theImage, 0, theNewArray, 0, imwidth * 2);
theBinaryWriter.Write(theNewArray);
Thread.Sleep(mScanThreadWait); //sleep for 50 milliseconds
Progress = (float)(y-1 >= 0 ? y-1 : 0) / (float)imheight;
}
theFS.Close();
ここまでは順調ですね。このコードは機能します。現在のバージョン(FileStreamとBinaryWriterを使用)は、同じオプションでFile.Openを使用し、ushort []のBinaryFormatterをディスクに書き込むのと同等のようです(ただし、コピーのために遅くなります)。
しかし、次にコンシューマースレッドを追加します。
FileStream theFS;
if (!File.Exists(theFileName)) {
//do error handling
return;
}
else {
theFS = new FileStream(theFileName, FileMode.Open,
FileAccess.Read, FileShare.Read);
//very relaxed file opening
}
BinaryReader theReader = new BinaryReader(theFS);
//gotta do this copying in order to handle byte array swaps
//frustrating, but true.
byte[] theNewArray = theReader.ReadBytes(
(int)(imheight * imwidth * inBase.Progress) * 2);
ushort[] theData = new ushort[((int)(theNewArray.Length/2))];
Buffer.BlockCopy(theNewArray, 0, theData, 0, theNewArray.Length);
これで、NewArrayの宣言が壊れて、ある種の読み取りオーバーフローが発生する可能性があります。ただし、このコードは、別のプロセスがファイルを開いたことを示すSystem.IO.IOExceptionを使用して新しいFileStreamを開こうとすると常に中断するため、それほど遠くまでは行きません。
MSDNのFileStreamドキュメントに記載されているようにFileAccessとFileShareの列挙を設定していますが、やりたいこと(つまり、あるスレッドでの書き込み、別のスレッドでの読み取り)ができないようです。このアプリケーションは少し変わっていることに気づきましたが、実際のデバイスを使用する場合は、同じことを行う必要がありますが、MFCを使用します。
とにかく、私は何を忘れていますか?ドキュメントで可能な限り指定されているので、私がやりたいことは可能ですか?
ありがとう!mmr