WPF memory leak from drag and drop

Using Red-Gate, we found that System.Windows.DataObject contains a reference to a dragObject (structure element) that has been hanging around from the operation since it was completed.

How to "clear" a drag object after DragDrop.DoDragDrop? Is there a way to pass a null value through this and skip it?

+4
source share
2 answers

I just opened this stone, my solution was to use WeakReference for a draggable data item.

DataObject data = new DataObject(new WeakReference(this.draggedData)); DragDrop.DoDragDrop((DependencyObject)sender, data, DragDropEffects.Move); 

and then in the frame

 var draggedItem = e.Data.GetData(this.format.Name) as WeakReference; if (draggedItem != null && draggedItem.IsAlive) { .... } 
+5
source

First of all, many thanks to Jan Oaks for his decision . However, I needed a small option: I had to make sure that the drop always worked, even if the garbage collector ran in the meantime. Here is the solution:

 public partial class DragDropDemo : Window { private SomeDragDropData _dragDropData; private void OnMouseMove(object sender, MouseEventArgs e) { if (e.LeftButton == MouseButtonState.Pressed) { _dragDropData = new SomeDragDropData { Text = "Some drag data" }; var dataObject = new DataObject("SomeObjectTypeId", new WeakReference<SomeDragDropData>(_dragDropData)); DragDrop.DoDragDrop((DependencyObject)sender, dataObject, DragDropEffects.Move); _dragDropData = null; } } private void OnDrop(object sender, DragEventArgs e) { var weakReferenceData = e.Data.GetData("SomeObjectTypeId") as WeakReference<SomeDragDropData>; if (weakReferenceData != null && weakReferenceData.IsAlive) MessageBox.Show(weakReferenceData.Target.Text); } } public class SomeDragDropData { public string Text; } 

Some notes:

  • The reason for this is that DoDragDrop blocks until the user performs a reset operation. Therefore, _dragDropData becomes null only after the drag and drop operation is completed.
  • It is very important to make _dragDropData a member variable. Just making it a local variable is not enough: when the garbage collector starts, the object can be deleted. This makes it very difficult to reproduce the error, because it is not because the garbage collector is started, that the object is necessarily cleared. From what I saw, it only clears when a large memory is allocated and freed.
+1
source

Source: https://habr.com/ru/post/1413092/


All Articles