WPF形状不会被垃圾收集 [英] WPF shape does not get garbage collected

查看:56
本文介绍了WPF形状不会被垃圾收集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述




我有一个简单的进度条形状,用于通知用户某些操作正在进行中。该形状扩展了Shape类,并在内部使用DispatcherTimer。每次计时器过去时,新几何项目都会添加到形状中。它还具有用于启动或停止计时器的IsRunning依赖属性。



该形状用于MVVM应用程序中的两个视图。应用程序使用TemplateSelector基于当前视图模型显示正确的视图。使用该形状的视图(用户控件)绑定其IsRunning d.p.视图模型上的IsRunning属性。



Hi
I have a simple progress-bar like shape used to notify the user that some operation is in progress. The shape extends the Shape class and internally uses a DispatcherTimer. Each time the timer elapses new geometry item is added to the shape. It also has the IsRunning dependency property used to start or stop the timer.

The shape is used on two views in a MVVM application. The application uses the TemplateSelector to show the correct view based on the current viewmodel. The views(user controls) which are using the shape bind its IsRunning d.p. to IsRunning property on the viewmodel.

<control:SimpleWaitControl IsRunning={Binding Path=IsRunning} />





以下是用于创建模板选择器的示例代码





Below is the sample code used to create a template selector

<selector:TemplateSelector x:Key="TemplateSelector">
   <selector:TempateSelector.View1Template>
      <DataTemplate>
         <view:View1 />
      </DataTemplate>
   </selector:TempateSelector.View1Template>
   ... templates for other views
</selector:TemplateSelector>





当我调试一些东西时,我添加了对形状的Start和Stop方法的记录(当IsRunning依赖属性的值被更改时调用的方法)并且发现当形状没有收集时视图从窗口中删除。 V.S中的输出窗口表示每次显示View1或View2时,都会构造并启动新形状,但随之启动所有先前构造的形状。因此,当第一次显示View1时,将构建一个新的SimpleWaitControl,但其中有5个已启动。当View1第5次被移除时,其中5个被停止。我错过了什么?据我所知,控制不能(也不必)处理。任何想法都会被证实。



Uros



While i was debugging some stuff I added logging to Start and Stop methods of the shape(methods called when the value of IsRunning dependency property is changed) amd found out that the shape does not get garbege collected when the view get removed from the window. The output window in V.S indicates that each time the View1 or View2 is shown new shape is constructed and started but with it all the shapes that were constructed previously are started. So when the View1 is shown for the 5th time one new SimpleWaitControl is constructed but 5 of them are started. When the View1 is removed for the 5th time all 5 of them get stopped. What am I missing? As far as I know the controls can not (and need not) be disposed. Any idea will appreaciated.

Uros

推荐答案

你不知道实际的垃圾收集可能会发生的不是你预期的(无论出于何种原因),但可能会在一段时间后发生。我完全不相信它不是垃圾收集的。我想,它发生了,但后来。你没有在你的描述中提到它。



GC的操作是由对象的可达性驱动的。在应用程序中无法预测对象析构函数的实际调用和回收内存的行为(顺便说一句,这就是为什么析构函数很少在典型的.NET应用程序中编写的原因,通常这不是必需的,并且可能会产生一些问题种族条件类型),但当某个物体变得无法到达时会发生。



顺便说一句,这个并不像你想象的那么简单。例如,如果对象A引用对象B,对象B引用对象C和C引用A,则此循环依赖性不会阻止GC确定如果没有其他对象引用,则应对所有对象进行垃圾回收。通过简单的实验很容易检查。



您可以在这里找到可达性和垃圾收集的详细信息:http://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29 [ ^ ]。



现在,你不应该认为在像CLR这样的内存管理系统中,内存泄漏是不可能的。这很有可能,但这里的问题是理解什么是内存泄漏。有关详细信息,请参阅我过去对此及相关主题的回答:

Garbage collectotion负责所有内存管理 [ ^ ],

推迟循环中的变量会导致内存泄漏吗? [ ^ ],

摆脱导致内存不足的公共静态列表的最佳方法 [ ^ ],

MDI表单中的内存管理 [ ^ ]。



祝你好运,

-SA
You are missing to understand that the actual garbage collection may happen not when you expected (by whatever reason), but it may happen some time later. I cannot believe it is not garbage-collected at all. I think, it happens, but later. You did not mention it in your description though.

The operation of GC is driven by the reachability of objects. The actual call of the object destructors and the act of reclaiming memory cannot be predicted bu the application (by the way, this is the reason why destructors are rarely written in the typical .NET applications, usually this is not needed and can created some problems of race conditions type), but it happens when some object becomes unreachable.

By the way, this is not so trivial criterion as you might think. For example, if object A references object B, object B references object C, and C reference A, this cyclic dependency does not prevent GC from figuring out that all objects should be garbage-collected if there are no other referenced to them. This is easy to check up by a simple experiment.

You can find the detail of reachability and garbage collection here: http://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29[^].

Now, you should not think that such thing as memory leak is impossible in a memory-managed system like CLR. It is quite possible, but the problem here is understanding what is a memory leak. For further detail, please see my past answers on this and related topics:
Garbage collectotion takes care of all the memory management[^],
deferring varirable inside the loop can cuase memory leak?[^],
Best way to get rid of a public static List Causing an Out of Memory[^],
Memory management in MDI forms[^].

Good luck,
—SA


这篇关于WPF形状不会被垃圾收集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆