UWP MapControl 非托管内存泄漏
UWP MapControl unmanaged memory leak
我有一个 MapControl
,我在其中添加了 MapIcons
和 Polylines
。
工作几分钟后,应用程序开始泄漏非托管内存并达到 8Gb。
请帮我找出一个错误。谢谢!
我用过 dotMemory profiler。下面的屏幕截图显示内存泄漏。
C#
Every second I redraw a MapControl (mainMap).
_timerUpdateDevices = ThreadPoolTimer.CreatePeriodicTimer(async (t) =>
{
// ... some managed code to prepare geodata ...
await mainMap.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
{
if (Interlocked.Read(ref canInsertNewCoordsForSelectedDeviceTracker) == 1)
{
RenderTracks(deviceID, tracker);
}
else
{
var trackLayer = cmap.CommonLayers.First(x => x.CMLayerType == CMLayerTypeEnum.Track);
var trackMapLayer = mainMap.Layers.FirstOrDefault(x => x.ZIndex == trackLayer.ZIndex);
if (trackMapLayer != null)
{
if (((MapElementsLayer)trackMapLayer).MapElements.Count > 0) ((MapElementsLayer)trackMapLayer).MapElements.Clear();
}
}
await RenderMap();
});
}, TimeSpan.FromSeconds(1));
private void RenderTracks(int deviceID, LGPSTracker tracker)
{
try
{
if (userSelectedDevice != null)
{
#region Track layer
var trackMapLayer = mainMap.Layers.FirstOrDefault(x => x.ZIndex == cmap.CommonLayers.First(x => x.CMLayerType == CMLayerTypeEnum.Track).ZIndex);
if (selectedDeviceTrackerPositions.Any() && selectedDeviceTrackerPositions.Count >= 2)
{
if (((MapElementsLayer)trackMapLayer).MapElements.Count > 0) // Update
{
((MapElementsLayer)trackMapLayer).MapElements.Clear(); // Clean
LTrackerPosition[][] chunks = null;
lock (selectedDeviceTrackerPositionsLock)
{
chunks = selectedDeviceTrackerPositions.Select((s, i) => new { Value = s, Index = i }).GroupBy(x => x.Index / 2).Select(grp => grp.Select(x => x.Value).ToArray()).ToArray();
}
LTrackerPosition lastInChunck = null;
for (int i = 0; i < chunks.Length; i++)
{
if (chunks[i].Length != 2) continue;
var firstPoint = chunks[i][0];
var secondPoint = chunks[i][1];
var mapPolyline = new MapPolyline();
var geoPositions = new List<BasicGeoposition>();
if (lastInChunck != null)
{
geoPositions.Add(new BasicGeoposition() { Latitude = lastInChunck.Lat, Longitude = lastInChunck.Lng });
}
geoPositions.Add(new BasicGeoposition() { Latitude = firstPoint.Lat, Longitude = firstPoint.Lng });
geoPositions.Add(new BasicGeoposition() { Latitude = secondPoint.Lat, Longitude = secondPoint.Lng });
mapPolyline.Path = new Geopath(geoPositions);
mapPolyline.StrokeColor = Colors.Blue;
mapPolyline.StrokeThickness = trackMapPolylineStrokeThickness;
mapPolyline.Tag = new TrackerView() { Position = firstPoint, Device = userSelectedDevice, Tracker = tracker };
((MapElementsLayer)trackMapLayer).MapElements.Add(mapPolyline);
lastInChunck = chunks[i][1];
}
}
else // Add
{
LTrackerPosition[][] chunks = null;
lock (selectedDeviceTrackerPositionsLock)
{
chunks = selectedDeviceTrackerPositions.Select((s, i) => new { Value = s, Index = i }).GroupBy(x => x.Index / 2).Select(grp => grp.Select(x => x.Value).ToArray()).ToArray();
}
LTrackerPosition lastInChunck = null;
for (int i = 0; i < chunks.Length; i++)
{
if (chunks[i].Length != 2) continue;
var firstPoint = chunks[i][0];
var secondPoint = chunks[i][1];
var mapPolyline = new MapPolyline();
var geoPositions = new List<BasicGeoposition>();
if (lastInChunck != null)
{
geoPositions.Add(new BasicGeoposition() { Latitude = lastInChunck.Lat, Longitude = lastInChunck.Lng });
}
geoPositions.Add(new BasicGeoposition() { Latitude = firstPoint.Lat, Longitude = firstPoint.Lng });
geoPositions.Add(new BasicGeoposition() { Latitude = secondPoint.Lat, Longitude = secondPoint.Lng });
mapPolyline.Path = new Geopath(geoPositions);
mapPolyline.StrokeColor = Colors.Blue;
mapPolyline.StrokeThickness = trackMapPolylineStrokeThickness;
mapPolyline.Tag = new TrackerView() { Position = firstPoint, Device = userSelectedDevice, Tracker = tracker };
((MapElementsLayer)trackMapLayer).MapElements.Add(mapPolyline);
lastInChunck = chunks[i][1];
}
}
}
#endregion
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
private async Task RenderMap()
{
var devices = ((App)Application.Current).Devices;
var trackers = ((App)Application.Current).Trackers;
var deviceTrackers = ((App)Application.Current).DeviceGPSTrackers;
foreach (var clayer in cmap.CommonLayers)
{
if (clayer.CMLayerType == CMLayerTypeEnum.Transport)
{
#region Tranport layer
var layer = mainMap.Layers.FirstOrDefault(x => x.ZIndex == clayer.ZIndex);
if (layer != null)
{
if (((MapElementsLayer)layer).MapElements.Count == 0)
{
List<TrackerView> trackerPoints = new List<TrackerView>();
var isCoordsInterpolating = DefaultSettings.GetIsCoordsInterpolating();
if (isCoordsInterpolating)
{
if (clayer.TrackerPoints.Count == 0) return;
trackerPoints = clayer.TrackerPoints.Select(d => d.Value).ToList<TrackerView>();
}
else
{
if (clayer.TrackerPoints.Count == 0) return;
trackerPoints = clayer.TrackerPoints.Select(d => d.Value).ToList<TrackerView>();
}
foreach (var trackerPoint in trackerPoints)
{
var bg = new BasicGeoposition { Latitude = trackerPoint.Position.Lat, Longitude = trackerPoint.Position.Lng };
var mi = new MapIcon
{
Location = new Geopoint(bg),
NormalizedAnchorPoint = new Point(0.5, 1.0),
ZIndex = 0,
Tag = trackerPoint,
IsEnabled = true,
Visible = true,
CollisionBehaviorDesired = MapElementCollisionBehavior.RemainVisible,
};
mi.Image = await GetDeviceStateIconStreamNormal(trackerPoint.Device.DeviceTypeID, 2, trackerPoint.Device.Name);
((MapElementsLayer)layer).MapElements.Add(mi);
}
}
else
{
#region Add cars
List<TrackerView> trackerPoints = new List<TrackerView>();
var isCoordsInterpolating = DefaultSettings.GetIsCoordsInterpolating();
if (isCoordsInterpolating)
{
if (clayer.TrackerPoints.Count == 0) return;
trackerPoints = clayer.TrackerPoints.Select(d => d.Value).ToList<TrackerView>();
}
else
{
if (clayer.TrackerPoints.Count == 0) return;
trackerPoints = clayer.TrackerPoints.Select(d => d.Value).ToList<TrackerView>();
}
var toAdd = new List<MapIcon>();
foreach (var trackerPoint in trackerPoints)
{
var isLayerElement = ((MapElementsLayer)layer).MapElements.FirstOrDefault(x => ((TrackerView)x.Tag).Device.ID == trackerPoint.Device.ID);
if (isLayerElement == null) // Добавить
{
var bg = new BasicGeoposition { Latitude = trackerPoint.Position.Lat, Longitude = trackerPoint.Position.Lng };
var mi = new MapIcon
{
Location = new Geopoint(bg),
NormalizedAnchorPoint = new Point(0.5, 1.0),
ZIndex = 0,
Tag = trackerPoint,
IsEnabled = true,
Visible = true,
CollisionBehaviorDesired = MapElementCollisionBehavior.RemainVisible,
};
if (userSelectedDevice != null) // Сделать прозрачным весьтранспорт кроме выделенного
{
if (userSelectedDevice.ID == trackerPoint.Device.ID)
{
mi.Image = await GetDeviceStateIconStreamSelected(trackerPoint.Device.DeviceTypeID, 2, trackerPoint.Device.Name);
}
else
{
mi.Image = await GetDeviceStateIconStreamFireless(trackerPoint.Device.DeviceTypeID, 2, trackerPoint.Device.Name, 0.4f);
}
}
else // Update
{
mi.Image = await GetDeviceStateIconStreamNormal(trackerPoint.Device.DeviceTypeID, 2, trackerPoint.Device.Name);
}
((MapElementsLayer)layer).MapElements.Add(mi);
}
else // Update
{
var mi = (MapIcon)isLayerElement;
var posMapElement = mi.Location.Position;
if (posMapElement.Latitude != trackerPoint.Position.Lat || posMapElement.Longitude != trackerPoint.Position.Lng)
{
var bg = new BasicGeoposition { Latitude = trackerPoint.Position.Lat, Longitude = trackerPoint.Position.Lng };
((MapIcon)isLayerElement).Location = new Geopoint(bg);
if (userSelectedDevice != null)
{
if (userSelectedDevice.ID == trackerPoint.Device.ID)
{
mi.Image = await GetDeviceStateIconStreamSelected(trackerPoint.Device.DeviceTypeID, 2, trackerPoint.Device.Name);
}
else
{
mi.Image = await GetDeviceStateIconStreamFireless(trackerPoint.Device.DeviceTypeID, 2, trackerPoint.Device.Name, 0.5f);
}
}
else
{
mi.Image = await GetDeviceStateIconStreamNormal(trackerPoint.Device.DeviceTypeID, 2, trackerPoint.Device.Name);
}
}
}
}
#endregion
#region Delete it from map
foreach (var device in devices.Where(x => x.IsEnabled == 0))
{
var isLayerElementExisting = ((MapElementsLayer)layer).MapElements.FirstOrDefault(x => ((TrackerView)x.Tag).Device.ID == device.ID);
if (isLayerElementExisting != null)
{
((MapElementsLayer)layer).MapElements.Remove(isLayerElementExisting);
}
}
#endregion
}
break;
}
#endregion
}
}
} // private void RenderMap()
// Create map icon on fly
private async Task<IRandomAccessStreamReference> GetDeviceStateIconStreamNormal(int deviceTypeID, int deviceStateID, string text)
{
try
{
var deviceTypeIcon = deviceTypeIcons.FirstOrDefault(x => x.DeviceTypeId == deviceTypeID && x.DeviceStateId == deviceStateID);
if (deviceTypeIcon != null)
{
var stream = new MemoryStream(deviceTypeIcon.IconFile);
var randomAccessStream = new InMemoryRandomAccessStream();
var outputStream = randomAccessStream.GetOutputStreamAt(0);
await RandomAccessStream.CopyAndCloseAsync(stream.AsInputStream(), outputStream);
var imagedecoder = await BitmapDecoder.CreateAsync(randomAccessStream);
var device = CanvasDevice.GetSharedDevice();
var renderTarget = new CanvasRenderTarget(device, imagedecoder.PixelWidth, imagedecoder.PixelHeight, 96);
using (var ds = renderTarget.CreateDrawingSession())
{
ds.Clear(Colors.Transparent);
Color color = Colors.Black;
var image = await CanvasBitmap.LoadAsync(device, randomAccessStream, 96);
var destinationRectangle = new Rect() { Width = imagedecoder.PixelWidth, Height = imagedecoder.PixelHeight, X = 1, Y = 1 };
var sourceRectangle = new Rect() { Width = imagedecoder.PixelWidth, Height = imagedecoder.PixelHeight, X = 1, Y = 1 };
ds.DrawImage(image, destinationRectangle, sourceRectangle);
ds.DrawText(text, new System.Numerics.Vector2(2, 1), color, new CanvasTextFormat()
{
FontSize = 12,
FontWeight = Windows.UI.Text.FontWeights.Bold
});
}
await renderTarget.SaveAsync(randomAccessStream, CanvasBitmapFileFormat.Png);
await randomAccessStream.FlushAsync();
return RandomAccessStreamReference.CreateFromStream(randomAccessStream);
}
else
{
return null; // TODO use default image
}
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
return null;
}
感谢 @JonasH
和 @Ed Pavlov
。
此代码没有任何内存泄漏问题。
我发现一些 lambda 表达式的泄漏 += (s,e) => 对于 Tile 的 MapControl 方法。所以我已经修好了。
无论如何,只需在几分钟内对 UWP MapControl 进行缩放 in/out 即可增加内存。
我有一个 MapControl
,我在其中添加了 MapIcons
和 Polylines
。
工作几分钟后,应用程序开始泄漏非托管内存并达到 8Gb。
请帮我找出一个错误。谢谢!
我用过 dotMemory profiler。下面的屏幕截图显示内存泄漏。
C#
Every second I redraw a MapControl (mainMap).
_timerUpdateDevices = ThreadPoolTimer.CreatePeriodicTimer(async (t) =>
{
// ... some managed code to prepare geodata ...
await mainMap.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
{
if (Interlocked.Read(ref canInsertNewCoordsForSelectedDeviceTracker) == 1)
{
RenderTracks(deviceID, tracker);
}
else
{
var trackLayer = cmap.CommonLayers.First(x => x.CMLayerType == CMLayerTypeEnum.Track);
var trackMapLayer = mainMap.Layers.FirstOrDefault(x => x.ZIndex == trackLayer.ZIndex);
if (trackMapLayer != null)
{
if (((MapElementsLayer)trackMapLayer).MapElements.Count > 0) ((MapElementsLayer)trackMapLayer).MapElements.Clear();
}
}
await RenderMap();
});
}, TimeSpan.FromSeconds(1));
private void RenderTracks(int deviceID, LGPSTracker tracker)
{
try
{
if (userSelectedDevice != null)
{
#region Track layer
var trackMapLayer = mainMap.Layers.FirstOrDefault(x => x.ZIndex == cmap.CommonLayers.First(x => x.CMLayerType == CMLayerTypeEnum.Track).ZIndex);
if (selectedDeviceTrackerPositions.Any() && selectedDeviceTrackerPositions.Count >= 2)
{
if (((MapElementsLayer)trackMapLayer).MapElements.Count > 0) // Update
{
((MapElementsLayer)trackMapLayer).MapElements.Clear(); // Clean
LTrackerPosition[][] chunks = null;
lock (selectedDeviceTrackerPositionsLock)
{
chunks = selectedDeviceTrackerPositions.Select((s, i) => new { Value = s, Index = i }).GroupBy(x => x.Index / 2).Select(grp => grp.Select(x => x.Value).ToArray()).ToArray();
}
LTrackerPosition lastInChunck = null;
for (int i = 0; i < chunks.Length; i++)
{
if (chunks[i].Length != 2) continue;
var firstPoint = chunks[i][0];
var secondPoint = chunks[i][1];
var mapPolyline = new MapPolyline();
var geoPositions = new List<BasicGeoposition>();
if (lastInChunck != null)
{
geoPositions.Add(new BasicGeoposition() { Latitude = lastInChunck.Lat, Longitude = lastInChunck.Lng });
}
geoPositions.Add(new BasicGeoposition() { Latitude = firstPoint.Lat, Longitude = firstPoint.Lng });
geoPositions.Add(new BasicGeoposition() { Latitude = secondPoint.Lat, Longitude = secondPoint.Lng });
mapPolyline.Path = new Geopath(geoPositions);
mapPolyline.StrokeColor = Colors.Blue;
mapPolyline.StrokeThickness = trackMapPolylineStrokeThickness;
mapPolyline.Tag = new TrackerView() { Position = firstPoint, Device = userSelectedDevice, Tracker = tracker };
((MapElementsLayer)trackMapLayer).MapElements.Add(mapPolyline);
lastInChunck = chunks[i][1];
}
}
else // Add
{
LTrackerPosition[][] chunks = null;
lock (selectedDeviceTrackerPositionsLock)
{
chunks = selectedDeviceTrackerPositions.Select((s, i) => new { Value = s, Index = i }).GroupBy(x => x.Index / 2).Select(grp => grp.Select(x => x.Value).ToArray()).ToArray();
}
LTrackerPosition lastInChunck = null;
for (int i = 0; i < chunks.Length; i++)
{
if (chunks[i].Length != 2) continue;
var firstPoint = chunks[i][0];
var secondPoint = chunks[i][1];
var mapPolyline = new MapPolyline();
var geoPositions = new List<BasicGeoposition>();
if (lastInChunck != null)
{
geoPositions.Add(new BasicGeoposition() { Latitude = lastInChunck.Lat, Longitude = lastInChunck.Lng });
}
geoPositions.Add(new BasicGeoposition() { Latitude = firstPoint.Lat, Longitude = firstPoint.Lng });
geoPositions.Add(new BasicGeoposition() { Latitude = secondPoint.Lat, Longitude = secondPoint.Lng });
mapPolyline.Path = new Geopath(geoPositions);
mapPolyline.StrokeColor = Colors.Blue;
mapPolyline.StrokeThickness = trackMapPolylineStrokeThickness;
mapPolyline.Tag = new TrackerView() { Position = firstPoint, Device = userSelectedDevice, Tracker = tracker };
((MapElementsLayer)trackMapLayer).MapElements.Add(mapPolyline);
lastInChunck = chunks[i][1];
}
}
}
#endregion
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
private async Task RenderMap()
{
var devices = ((App)Application.Current).Devices;
var trackers = ((App)Application.Current).Trackers;
var deviceTrackers = ((App)Application.Current).DeviceGPSTrackers;
foreach (var clayer in cmap.CommonLayers)
{
if (clayer.CMLayerType == CMLayerTypeEnum.Transport)
{
#region Tranport layer
var layer = mainMap.Layers.FirstOrDefault(x => x.ZIndex == clayer.ZIndex);
if (layer != null)
{
if (((MapElementsLayer)layer).MapElements.Count == 0)
{
List<TrackerView> trackerPoints = new List<TrackerView>();
var isCoordsInterpolating = DefaultSettings.GetIsCoordsInterpolating();
if (isCoordsInterpolating)
{
if (clayer.TrackerPoints.Count == 0) return;
trackerPoints = clayer.TrackerPoints.Select(d => d.Value).ToList<TrackerView>();
}
else
{
if (clayer.TrackerPoints.Count == 0) return;
trackerPoints = clayer.TrackerPoints.Select(d => d.Value).ToList<TrackerView>();
}
foreach (var trackerPoint in trackerPoints)
{
var bg = new BasicGeoposition { Latitude = trackerPoint.Position.Lat, Longitude = trackerPoint.Position.Lng };
var mi = new MapIcon
{
Location = new Geopoint(bg),
NormalizedAnchorPoint = new Point(0.5, 1.0),
ZIndex = 0,
Tag = trackerPoint,
IsEnabled = true,
Visible = true,
CollisionBehaviorDesired = MapElementCollisionBehavior.RemainVisible,
};
mi.Image = await GetDeviceStateIconStreamNormal(trackerPoint.Device.DeviceTypeID, 2, trackerPoint.Device.Name);
((MapElementsLayer)layer).MapElements.Add(mi);
}
}
else
{
#region Add cars
List<TrackerView> trackerPoints = new List<TrackerView>();
var isCoordsInterpolating = DefaultSettings.GetIsCoordsInterpolating();
if (isCoordsInterpolating)
{
if (clayer.TrackerPoints.Count == 0) return;
trackerPoints = clayer.TrackerPoints.Select(d => d.Value).ToList<TrackerView>();
}
else
{
if (clayer.TrackerPoints.Count == 0) return;
trackerPoints = clayer.TrackerPoints.Select(d => d.Value).ToList<TrackerView>();
}
var toAdd = new List<MapIcon>();
foreach (var trackerPoint in trackerPoints)
{
var isLayerElement = ((MapElementsLayer)layer).MapElements.FirstOrDefault(x => ((TrackerView)x.Tag).Device.ID == trackerPoint.Device.ID);
if (isLayerElement == null) // Добавить
{
var bg = new BasicGeoposition { Latitude = trackerPoint.Position.Lat, Longitude = trackerPoint.Position.Lng };
var mi = new MapIcon
{
Location = new Geopoint(bg),
NormalizedAnchorPoint = new Point(0.5, 1.0),
ZIndex = 0,
Tag = trackerPoint,
IsEnabled = true,
Visible = true,
CollisionBehaviorDesired = MapElementCollisionBehavior.RemainVisible,
};
if (userSelectedDevice != null) // Сделать прозрачным весьтранспорт кроме выделенного
{
if (userSelectedDevice.ID == trackerPoint.Device.ID)
{
mi.Image = await GetDeviceStateIconStreamSelected(trackerPoint.Device.DeviceTypeID, 2, trackerPoint.Device.Name);
}
else
{
mi.Image = await GetDeviceStateIconStreamFireless(trackerPoint.Device.DeviceTypeID, 2, trackerPoint.Device.Name, 0.4f);
}
}
else // Update
{
mi.Image = await GetDeviceStateIconStreamNormal(trackerPoint.Device.DeviceTypeID, 2, trackerPoint.Device.Name);
}
((MapElementsLayer)layer).MapElements.Add(mi);
}
else // Update
{
var mi = (MapIcon)isLayerElement;
var posMapElement = mi.Location.Position;
if (posMapElement.Latitude != trackerPoint.Position.Lat || posMapElement.Longitude != trackerPoint.Position.Lng)
{
var bg = new BasicGeoposition { Latitude = trackerPoint.Position.Lat, Longitude = trackerPoint.Position.Lng };
((MapIcon)isLayerElement).Location = new Geopoint(bg);
if (userSelectedDevice != null)
{
if (userSelectedDevice.ID == trackerPoint.Device.ID)
{
mi.Image = await GetDeviceStateIconStreamSelected(trackerPoint.Device.DeviceTypeID, 2, trackerPoint.Device.Name);
}
else
{
mi.Image = await GetDeviceStateIconStreamFireless(trackerPoint.Device.DeviceTypeID, 2, trackerPoint.Device.Name, 0.5f);
}
}
else
{
mi.Image = await GetDeviceStateIconStreamNormal(trackerPoint.Device.DeviceTypeID, 2, trackerPoint.Device.Name);
}
}
}
}
#endregion
#region Delete it from map
foreach (var device in devices.Where(x => x.IsEnabled == 0))
{
var isLayerElementExisting = ((MapElementsLayer)layer).MapElements.FirstOrDefault(x => ((TrackerView)x.Tag).Device.ID == device.ID);
if (isLayerElementExisting != null)
{
((MapElementsLayer)layer).MapElements.Remove(isLayerElementExisting);
}
}
#endregion
}
break;
}
#endregion
}
}
} // private void RenderMap()
// Create map icon on fly
private async Task<IRandomAccessStreamReference> GetDeviceStateIconStreamNormal(int deviceTypeID, int deviceStateID, string text)
{
try
{
var deviceTypeIcon = deviceTypeIcons.FirstOrDefault(x => x.DeviceTypeId == deviceTypeID && x.DeviceStateId == deviceStateID);
if (deviceTypeIcon != null)
{
var stream = new MemoryStream(deviceTypeIcon.IconFile);
var randomAccessStream = new InMemoryRandomAccessStream();
var outputStream = randomAccessStream.GetOutputStreamAt(0);
await RandomAccessStream.CopyAndCloseAsync(stream.AsInputStream(), outputStream);
var imagedecoder = await BitmapDecoder.CreateAsync(randomAccessStream);
var device = CanvasDevice.GetSharedDevice();
var renderTarget = new CanvasRenderTarget(device, imagedecoder.PixelWidth, imagedecoder.PixelHeight, 96);
using (var ds = renderTarget.CreateDrawingSession())
{
ds.Clear(Colors.Transparent);
Color color = Colors.Black;
var image = await CanvasBitmap.LoadAsync(device, randomAccessStream, 96);
var destinationRectangle = new Rect() { Width = imagedecoder.PixelWidth, Height = imagedecoder.PixelHeight, X = 1, Y = 1 };
var sourceRectangle = new Rect() { Width = imagedecoder.PixelWidth, Height = imagedecoder.PixelHeight, X = 1, Y = 1 };
ds.DrawImage(image, destinationRectangle, sourceRectangle);
ds.DrawText(text, new System.Numerics.Vector2(2, 1), color, new CanvasTextFormat()
{
FontSize = 12,
FontWeight = Windows.UI.Text.FontWeights.Bold
});
}
await renderTarget.SaveAsync(randomAccessStream, CanvasBitmapFileFormat.Png);
await randomAccessStream.FlushAsync();
return RandomAccessStreamReference.CreateFromStream(randomAccessStream);
}
else
{
return null; // TODO use default image
}
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
return null;
}
感谢 @JonasH
和 @Ed Pavlov
。
此代码没有任何内存泄漏问题。
我发现一些 lambda 表达式的泄漏 += (s,e) => 对于 Tile 的 MapControl 方法。所以我已经修好了。
无论如何,只需在几分钟内对 UWP MapControl 进行缩放 in/out 即可增加内存。