我的问题基于继承了大量无法改变的遗留代码。基本上,我有一个会产生数据块的设备。一个库将调用这个设备来创建该数据块,出于某些原因,即使我想要改变也完全不理解,该库会将该数据块写入磁盘。
这个写入不是瞬间完成的,可能需要长达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);
现在声明theNewArray可能存在问题,可能会导致某种类型的读取溢出。但是,由于始终在尝试使用System.IO.IOException打开新的FileStream时就会中断,因为另一个进程已经打开了该文件,所以这段代码永远不会到达那一步。
我按照MSDN上的FileStream文档设置了FileAccess和FileShare枚举,但似乎我不能做我想做的事情(即在一个线程中写入,在另一个线程中读取)。我知道这个应用程序有点不正常,但当我涉及到实际设备时,我将不得不做同样的事情,但使用MFC。
总之,我忘记了什么?我想要做的事情是否可能,因为在文档中指定为可能?
谢谢! mmr