I'm running the following code in LinqPad 5:
var client = new MongoClient(@"mongodb://192.168.0.108:27017");
var db = client.GetDatabase("Stfc");
var fitCollection = db.GetCollection<ModelFit>("RecentFits");
var fits = fitCollection.AsQueryable();
var captureCollection = db.GetCollection<Capture>("Captures");
var captures = captureCollection.AsQueryable();
var classificationCollection = db.GetCollection<Classification>("Classifications");
var classifications = classificationCollection.AsQueryable();
var modelsDir = new DirectoryInfo(@"\\iansdesktop\Shared\Stfc\mymodels");
var imagesDir = new DirectoryInfo(@"\\iansdesktop\Shared\Stfc\Images");
var classificationDir = new DirectoryInfo(@"C:\Users\Ian\Documents\Projects\Output\StfcBot\Classification");
var capturesById = captures.ToDictionary(x => x.Id);
var systems = classifications
.Where(x => x.Label == "system");
var count = systems.Count();
var i = 0;
var pen = new Pen(Color.FromArgb(255, 255, 0, 0));
foreach (var classification in systems)
{
var capture = capturesById[classification.CaptureId];
var img = imagesDir.File(capture.ImageName);
var srcFile = imagesDir.File(capture.ImageName);
var destFile = classificationDir.File(capture.ImageName);
while (!destFile.Exists)
{
try
{
using (var bmp = Bitmap.FromFile(srcFile.FullName))
using (var dest = new Bitmap(bmp))
{
using (var g = Graphics.FromImage(dest))
{
g.DrawEllipse(pen, capture.X - 20, capture.Y - 20, 40, 40);
}
dest.Save(destFile.FullName);
dest.Dispose();
bmp.Dispose();
}
destFile.Refresh();
destFile.Name.Dump();
}
catch (IOException ex)
{
ex.Dump();
Thread.Sleep(30_000);
}
}
++i;
if (i % 10 == 0)
{
i.ToProgressSummary(count).Dump();
}
}
Am I missing anything, or could this be a bug in LinqPad?
Turns out this is because the bitmap was being loaded from a network path, and the network was occasionally disconnecting.
The documentation states:
You must keep the stream open for the lifetime of the Bitmap.
Bitmap Constructors (See Remarks)
The OOM exception obfuscates what is going on for some reason, but the underlying stream was being closed.
The solution is to copy the file locally and operate on that local copy:
var tmpFile = new DirectoryInfo(Path.GetTempPath()).File(srcFile.Name);
while (!destFile.Exists)
{
srcFile.CopyTo(tmpFile.FullName);
try
{
using (var bmp = Bitmap.FromFile(tmpFile.FullName))
using (var dest = new Bitmap(bmp))
{
.
}
destFile.Refresh();
destFile.Name.Dump();
}
catch (IOException ex)
{
...
}
finally
{
tmpFile.Delete();
}
}
Of course if the network still disconnects an exception occurs, but at least it's a sensible and understandable error instead of OOM.