Page MenuHomePhabricator

C#: CA2000: Dispose objects before losing scope
Closed, ResolvedPublic

Description

Some disposable resources are "leaking" to the garbage collector.. We could explicitly call dispose or use them inside using blocks.

lauromoura triaged this task as Normal priority.

Taking a look at some of the most complicated cases in generated code, Here is a table of the occurrences:

FunctionVariable typeNotes
efl_ui_focus_composition_element_set@in @move Eina.List<Efl.Gfx.Entity>input from native to managed code. Affects both Calendar and Spin_Button
efl_ui_focus_manager_calc_update_children@move Eina.List<Efl.Ui.Focus.IObject>input from native to managed code
efl_ui_focus_manager_calc_update_order@move Eina.List<Efl.Ui.Focus.IObject>input from native to managed code
efl_container_model_child_property_add@move Eina.Iterator<IntPtr>input from native to managed code
efl_core_command_line_array_set@move Eina.Array<Eina.Stringshare @move>from native to managed code
efl_loop_future_resolvedEina.ValuePassed by "value". The returned Future should take care of releasing the value.
efl_loop_quitEina.ValuePassed by "value"
efl_ui_win_wm_available_profiles_setEina.Array<System.String>const(array<string>)
efl_gfx_image_stretch_region_getEina.Iterator<Efl.Gfx.ImageStretchRegion> (for horizonal and vertical)out iterators
efl_gfx_image_stretch_region_setEina.Iterator<Efl.Gfx.ImageStretchRegion> (for horizonal and vertical)in iterators
efl_ui_factory_release@move Eina.Iterator<Efl.Gfx.IEntity>from native to managed code
efl_ui_format_values_setEina.Accessor<Efl.Ui.FormatValue>passed from native code to managed code
efl_ui_factory_create@move Eina.Iterator<Efl.IModel>from native to managed code
efl_ui_view_factory_create_with_eventyEina.Iterator<Efl.IModel>from native code to managed code
efl_ui_view_model_property_logic_addEina.Iterator<String>passed from native code to managed code
efl_ui_tags_items_setEina.Array<String>passed from native code to managed code.

Given the user's C# overriding method can end up storing the value somewhere, this may make calling Dispose on these variables impossible/dangerous.

I think we could suppress the warning for theses cases (in fact, for all native overrides) and rely on the GC to cleanup them.

What do you think @YOhoho @felipealmeida ?

I agree to this opinion. the native handle of those parameters would be used in native code.

In summary, C was evil because programmers could forget to free their resources, so humankind created C# that frees resources for you. And now CA2000 is telling me that I should free resources manually again? What's wrong with the world?

In summary, C was evil because programmers could forget to free their resources, so humankind created C# that frees resources for you. And now CA2000 is telling me that I should free resources manually again? What's wrong with the world?

The reasoning behind CA2000 is focused on unmanaged resources (wrapped by IDisposable instances), like open files, open sockets, EO instances.

The GC knows about managed memory but has no idea a native resource is waiting to be reclaimed, treating them as plain managed instances. For example, opening up a 4K Efl.Ui.Image could look like a plain Efl.Object for the GC.

One thing we could do to mitigate this would be adding/removing some "memory pressure" to tell the GC things are taking up memory. This could be useful for memory heavy instances like images.

lauromoura closed this task as Resolved.Nov 14 2019, 7:47 PM
lauromoura claimed this task.

Fixed after these commits.

Enabled CA2000 in devs/lauromoura/stylecop