J'ai une petite application d'exemple que je travaillais à essayer d'obtenir quelques-uns des nouveaux .Net 4.0 extensions parallèles vont (ils sont très gentils). Je cours dans un problème (probablement vraiment stupide) avec une OutOfMemoryException. Mon application principale que je cherche à brancher cet échantillon dans des lectures de certaines données et beaucoup de fichiers, fait un peu de traitement sur eux, puis les écrit quelque part. Je rencontrais quelques problèmes avec les fichiers qui grossissaient (peut-être GB's) et j'étais préoccupé par la mémoire, donc je voulais paralléliser les choses qui m'ont conduit dans cette voie.OutOfMemoryException sur MemoryStream écrit
Maintenant, le code ci-dessous obtient un oome sur des fichiers plus petits et je pense que je suis juste manque quelque chose. Il va lire dans 10-15 fichiers et les écrire en parellel bien, mais alors il étouffe sur le prochain. On dirait qu'il est lu et écrit sur 650Mo. Un deuxième ensemble d'yeux serait apprécié.
Je lis un MemorySteam à partir du FileStream parce que c'est ce qui est nécessaire pour l'application principale et j'essaie juste de le répliquer dans une certaine mesure. Il lit les données et les fichiers de tous les types d'endroits et travaille sur eux comme MemoryStreams.
Ce utilise .Net 4.0 Beta 2, VS 2010.
namespace ParellelJob
{
class Program
{
BlockingCollection<FileHolder> serviceToSolutionShare;
static void Main(string[] args)
{
Program p = new Program();
p.serviceToSolutionShare = new BlockingCollection<FileHolder>();
ServiceStage svc = new ServiceStage(ref p.serviceToSolutionShare);
SolutionStage sol = new SolutionStage(ref p.serviceToSolutionShare);
var svcTask = Task.Factory.StartNew(() => svc.Execute());
var solTask = Task.Factory.StartNew(() => sol.Execute());
while (!solTask.IsCompleted)
{
}
}
}
class ServiceStage
{
BlockingCollection<FileHolder> outputCollection;
public ServiceStage(ref BlockingCollection<FileHolder> output)
{
outputCollection = output;
}
public void Execute()
{
var di = new DirectoryInfo(@"C:\temp\testfiles");
var files = di.GetFiles();
foreach (FileInfo fi in files)
{
using (var fs = new FileStream(fi.FullName, FileMode.Open, FileAccess.Read))
{
int b;
var ms = new MemoryStream();
while ((b = fs.ReadByte()) != -1)
{
ms.WriteByte((byte)b); //OutOfMemoryException Occurs Here
}
var f = new FileHolder();
f.filename = fi.Name;
f.contents = ms;
outputCollection.TryAdd(f);
}
}
outputCollection.CompleteAdding();
}
}
class SolutionStage
{
BlockingCollection<FileHolder> inputCollection;
public SolutionStage(ref BlockingCollection<FileHolder> input)
{
inputCollection = input;
}
public void Execute()
{
FileHolder current;
while (!inputCollection.IsCompleted)
{
if (inputCollection.TryTake(out current))
{
using (var fs = new FileStream(String.Format(@"c:\temp\parellel\{0}", current.filename), FileMode.OpenOrCreate, FileAccess.Write))
{
using (MemoryStream ms = (MemoryStream)current.contents)
{
ms.WriteTo(fs);
current.contents.Close();
}
}
}
}
}
}
class FileHolder
{
public string filename { get; set; }
public Stream contents { get; set; }
}
}
pré-allocation du MemoryStream résout mon problème pour tous les fichiers sauf les plus volumineux. Je vais diviser des fichiers plus gros en morceaux. Je n'avais pas cela dans cet exemple d'application. Merci. – MikeD