बिटमैपडेकोडर, बिटमैपप्रॉपर्टीसेट, और बिटमैप टाइपेड वैल्यू के नीचे उपयोग मूल स्मृति में एक रिसाव का कारण बनता है। मुझे आशा है कि मैं बस उन्हें गलत तरीके से उपयोग कर रहा हूं ... उनका उपयोग करने का सही तरीका क्या है? वे IDISposable लागू नहीं करते हैं, इसलिए मुझे यकीन नहीं है कि उन्हें अपनी मूल स्मृति को मुक्त करने के लिए कैसे बताना है।देशी मेमोरी में रिसाव के बिना आप किसी छवि के मेटाडेटा को कैसे एक्सेस करते हैं?
एक मौका है कि इस रिसाव से बचा नहीं जा सकता है। यदि हां, तो मैं अपने यूडब्ल्यूपी ऐप को इसके प्रभाव से कैसे ढाल दूंगा?
विंडोज प्रदर्शन रिकॉर्डर/विश्लेषक से एक वलोक ट्रेस कोई डिकॉमिट टाइम के साथ कई आवंटन दिखाता है। इन वस्तुओं के लिए कमिट स्टैक इंगित करते हैं कि वे मेटाडेटा लाने से संबंधित हैं या मेटाडेटा के टुकड़े हैं।
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks;
using Windows.Graphics.Imaging;
using Windows.Storage;
using Windows.Storage.Search;
namespace Tests
{
[TestClass]
public class TestBitmapDecoderLeak
{
// Path to a folder containing jpeg's that have metadata.
private static readonly string ImageFolderPath = @"path to folder of jpegs";
// The subset of the metadata you want to get
private static readonly string [] MetadataPolicies =
{
"System.Copyright",
"System.SimpleRating",
"System.Photo.ShutterSpeed",
"System.Photo.Aperture",
"System.Photo.CameraModel",
"System.Photo.CameraManufacturer",
"System.Photo.DateTaken",
"System.Photo.ExposureTime",
"System.Photo.Flash",
"System.Photo.FlashEnergy",
"System.Photo.ISOSpeed",
"System.GPS.Longitude",
"System.GPS.Latitude"
};
[TestMethod]
public async Task RunTest()
{
// Start your profiler
Debugger.Break();
var imageFiles = await GetJpegFiles();
// Get some metadata for each image, but do nothing with it.
foreach (var imageFile in imageFiles)
{
using (var fileStream = await imageFile.OpenReadAsync())
{
var decoder = await BitmapDecoder.CreateAsync(fileStream);
var DpiX = decoder.DpiX;
var DpiY = decoder.DpiY;
var PixelSizeWidth = decoder.OrientedPixelWidth;
var PixelSizeHeight = decoder.OrientedPixelHeight;
var DecoderId = decoder.DecoderInformation.CodecId;
var properties = await decoder.BitmapProperties.GetPropertiesAsync(MetadataPolicies);
var ShutterSpeed = NullOrValType<double>(properties, "System.Photo.ShutterSpeed");
var Copyright = NullOrRefType<string>(properties, "System.Copyright");
var SimpleRating = NullOrValType<UInt16>(properties, "System.SimpleRating");
var Aperture = NullOrValType<double>(properties, "System.Photo.Aperture");
var CameraModel = NullOrRefType<string>(properties, "System.Photo.CameraModel");
var DateTaken = NullOrValType<DateTimeOffset>(properties, "System.Photo.DateTaken");
var ExposureTime = NullOrValType<double>(properties, "System.Photo.ExposureTime");
var Flash = NullOrValType<UInt16>(properties, "System.Photo.Flash");
var FlashEnergy = NullOrValType<double>(properties, "System.Photo.FlashEnergy");
var IsoSpeed = NullOrValType<UInt16>(properties, "System.Photo.ISOSpeed");
var Longitude = NullOrRefType<double[]>(properties, "System.GPS.Longitude");
var Latitude = NullOrRefType<double[]>(properties, "System.GPS.Latitude");
}
}
// Remove these so they don't add noise to the trace
imageFiles = null;
// Ensure everything is cleaned up to the best of the GC's abilities
GC.Collect();
GC.WaitForPendingFinalizers();
// Stop your profiler
Debugger.Break();
}
private static async Task<IEnumerable<StorageFile>> GetJpegFiles()
{
var folder = await StorageFolder.GetFolderFromPathAsync(ImageFolderPath);
var queryOptions = new QueryOptions
{
FolderDepth = FolderDepth.Deep,
IndexerOption = IndexerOption.DoNotUseIndexer,
};
queryOptions.FileTypeFilter.Add(".jpg");
queryOptions.FileTypeFilter.Add(".jpeg");
queryOptions.FileTypeFilter.Add(".jpe");
var folderQuery = folder.CreateFileQueryWithOptions(queryOptions);
return await folderQuery.GetFilesAsync();
}
private static T NullOrRefType<T>(IDictionary<string, BitmapTypedValue> properties, string policy)
where T : class
{
if (properties == null || !properties.ContainsKey(policy))
return null;
return (T)properties[policy].Value;
}
private static T? NullOrValType<T>(IDictionary<string, BitmapTypedValue> properties, string policy)
where T : struct
{
if (properties == null || !properties.ContainsKey(policy))
return null;
return (T)properties[policy].Value;
}
}
}