|
|
|
Forum Newbie
      
Group: Forum Members
Last Login: 2010-05-20 17:30:04
Posts: 7,
Visits: 24
|
|
I am getting an OutOfMemoryException when retrieving images from my SQLite database. My Observation object has many ObservationImage objects which have an ImageData property containing a jpg image file (about 5MB per file). I am looping through these images and streaming them to a directory on the local filesystem. After about 50 Observations (100 images) I get this exception.
Is there a way of clearing the memory used by the image after I have used its data (after exporting to a directory)?
My Code is as follows:
foreach (Observation Obs in Surv.Observations) {
DirPath = outputPath + String.Format("\\Obs {0}", Obs.ID);
ExportObservationImagesToPath(Obs, DirPath);
prog.Position = ObsNum++;
prog.Update();
}
private void ExportObservationImagesToPath(Observation obs, string dirPath) {
if (!Directory.Exists(dirPath)) Directory.CreateDirectory(dirPath);
string FilePath;
byte[] BinData;
int ImageNum = 1;
foreach (ObservationImage Image in obs.ObservationImages) {
FilePath = Path.Combine(dirPath, string.Format("Obs {0} Image {1}.jpg", obs.ID, ImageNum++));
BinData = Image.ImageData;
BinaryFile.SaveBufferToFile(ref BinData, FilePath);
}
}
The exception detail is as follows;
System.InvalidOperationException was unhandled by user code
Message="Error retrieving data for ObservationImage.ImageData: An error occurred when reading query field value for ObservationImage.ImageData\rError: OutOfMemoryException\rMessage: Exception of type 'System.OutOfMemoryException' was thrown."
Source="Eco.Persistence"
StackTrace:
at Eco.Persistence.Impl.ClassPersistenceMapper.ValuesFromFieldsByMemberList(ObjectContents ObjContents, InexactIdList RequiresExactification, IDataSet DataSet, TBoldMemberPersistenceMapperList memberList) in e:\dev\fbuild\source\Eco\Eco.Persistence\FromCore\ClassPersistenceMapper.cs:line 840
at Eco.Persistence.Impl.ClassPersistenceMapper.PMMultiPurposeRetrieveExactIdList(IDatabaseCollection Databases, ObjectIdCollection ObjectsToFetch, Datablock Precondition, Int32[] MemberIdList, FetchMode FetchMode, IdTranslationList TranslationList, Datablock FailureList, Int32 Timestamp, FetchStrategy fetchStrategy) in e:\dev\fbuild\source\Eco\Eco.Persistence\FromCore\ClassPersistenceMapper.cs:line 1542
... other detail deleted ....
Any help would be gratefully received,
VS2008 SP 1 ECO5 (latest release version)
Mike
|
|
|
|
|
Supreme Being
      
Group: Forum Members
Last Login: 2011-07-14 17:05:00
Posts: 290,
Visits: 2 617
|
|
Hi Mike
When you load these objects ECO keeps them in its cache until you close the EcoSpace, which means each image data remains in memory. There are two ways you can tackle this
Solution 1:
Make sure the image data is marked as DelayedFetch=True
Pass the ExternalID rather than the Observation object
Create an EcoSpace, get the object by its ExternalID, Save the image, dispose of the EcoSpace
1 initial select to get the list of observation + 1 select for each observation data + 1 select for each delayed fetched image data
Solution 2:
Make sure the image data is marked as DelayedFetch=True
After passing the Observation object to your routine which saves the image unload it
1 initial select to get the list of observation + 1 select for each 50 observation data objects + 1 select for each delayed fetched image data
foreach(var observation in Meh.Observations)
{
SaveTheImage(observation, .........);
observation.AsIObject().ServiceProvider.GetEcoService().Unload(new List { observation });
}
I think the latter will work, give it a try, but either way you really want a DelayedFetch=True
====
Pete
|
|
|
|
|
Forum Newbie
      
Group: Forum Members
Last Login: 2010-05-20 17:30:04
Posts: 7,
Visits: 24
|
|
Thanks Pete,
I adopted your second approach which seems to have solved the issue. Many thanks as always.
Regards
Mike
|
|
|
|