Ma question est basée sur l'héritage de beaucoup de code hérité que je ne peux pas faire beaucoup. Fondamentalement, j'ai un appareil qui va produire un bloc de données. Une bibliothèque qui appelle l'appareil pour créer ce bloc de données, pour une raison que je ne comprends pas complètement et ne peut pas changer même si je le voulais, écrit ce bloc de données sur le disque.Le fichier C# en lecture/écriture Le partage de fichiers ne semble pas fonctionner
Cette écriture n'est pas instantanée mais peut durer jusqu'à 90 secondes. Pendant ce temps, l'utilisateur veut obtenir une vue partielle des données qui sont produites, donc je veux avoir un thread consommateur qui lit les données que l'autre bibliothèque écrit sur le disque. Avant que je ne touche même ce code hérité, je veux imiter le problème en utilisant le code que je contrôle entièrement. J'utilise C#, ostensiblement parce qu'il fournit beaucoup de fonctionnalités que je veux.
Dans la classe de producteur, j'ai ce code créer un bloc aléatoire de données:
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();
Jusqu'à présent, si bon. Ce code fonctionne. La version actuelle (en utilisant FileStream et BinaryWriter) semble être équivalente (bien que plus lente, à cause de la copie) à l'utilisation de File.Open avec les mêmes options et un BinaryFormatter sur l'ushort [] étant écrit sur le disque.
Mais j'ajouter un fil à la consommation:
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);
Maintenant, il est possible que la déclaration de theNewArray est rompue, et provoquera une sorte de débordement de lecture. Cependant, ce code ne va jamais aussi loin, car il interrompt toujours toujours l'ouverture du nouveau FileStream avec une exception System.IO.IOException qui indique qu'un autre processus a ouvert le fichier. Je définis les énumérations FileAccess et FileShare comme indiqué dans la documentation FileStream sur MSDN, mais il semble que je ne peux pas faire ce que je veux faire (écrire dans un thread, lire dans un autre thread). Je me rends compte que cette application est un peu peu orthodoxe, mais quand je reçois le périphérique réel impliqué, je vais devoir faire la même chose, mais en utilisant MFC.
Dans tous les cas, qu'est-ce que j'oublie? Est ce que je veux faire possible, puisque c'est spécifié comme possible dans la documentation?
Merci! MMR
Assez bien - mais rappelez-vous, je dois le faire avec du code hérité qui n'a presque certainement aucun verrou de fichier (et les personnes qui ont écrit ce code vous regarderait comme si vous étiez folle de suggérer qu'il y a de telles choses). Donc, si ça casse à cause de ça, je ferais mieux d'imiter ces pauses. – mmr