Meine Frage basiert auf der Übernahme einer großen Menge von Legacy-Code, über den ich nicht viel machen kann. Grundsätzlich habe ich ein Gerät, das einen Datenblock erzeugt. Eine Bibliothek, die das Gerät anruft, um diesen Datenblock zu erzeugen, aus irgendeinem Grund, den ich nicht vollständig verstehe und nicht ändern kann, selbst wenn ich das wollte, schreibt diesen Datenblock auf die Festplatte.C# -Datei lesen/schreiben Fileshare scheint nicht zu funktionieren
Dieser Schreibvorgang erfolgt nicht sofort, sondern kann bis zu 90 Sekunden dauern. In dieser Zeit möchte der Benutzer eine Teilansicht der Daten erhalten, die gerade produziert werden. Daher möchte ich einen Consumer-Thread haben, der die Daten liest, die die andere Bibliothek auf die Festplatte schreibt.
Bevor ich diesen Legacy-Code anfasse, möchte ich das Problem mit dem Code, den ich vollständig kontrolliere, nachahmen. Ich benutze C#, angeblich weil es eine Menge der Funktionalität bietet, die ich will.
In der Hersteller-Klasse habe ich diesen Code einen Zufallsdatenblock zu erstellen:
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();
So weit, so gut. Dieser Code funktioniert. Die aktuelle Version (mit FileStream und BinaryWriter) scheint (wegen der Kopie langsamer) zu sein, File.Open mit den gleichen Optionen zu verwenden und einen BinaryFormatter auf dem ushort [] auf den Datenträger zu schreiben.
Aber dann füge ich einen Verbraucher thread:
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);
Jetzt ist es möglich, dass die Erklärung von theNewArray gebrochen ist, und wird eine Art von Leseüberlauf verursachen. Dieser Code kommt jedoch nie so weit, weil er beim Öffnen des neuen FileStreams immer mit einer System.IO.IOException, die besagt, dass ein anderer Prozess die Datei geöffnet hat, immer immer bricht.
Ich setze die FileAccess- und FileShare-Enumerationen wie in der FileStream-Dokumentation auf MSDN angegeben, aber es scheint, dass ich einfach nicht tun kann, was ich tun möchte (dh in einen Thread schreiben, einen anderen einlesen). Ich stelle fest, dass diese Anwendung ein wenig unorthodox ist, aber wenn ich das tatsächliche Gerät involviere, werde ich das gleiche tun müssen, aber MFC verwenden.
Auf jeden Fall, was vergesse ich? Ist das, was ich tun möchte möglich, da es in der Dokumentation als möglich angegeben ist?
Danke! MMR
Fair genug-- aber denken Sie daran, ich muss dies mit Legacy-Code, der fast sicher keine Dateisperren hat (und die Leute, die diesen Code geschrieben haben) tun würde dich ansehen, als wärst du verrückt dafür, dass es solche Dinge gibt). Also, wenn es deswegen bricht, ahme ich diese Pausen am besten nach. – mmr