[Gtk-sharp-list] widget destruction

Lluis Sanchez Gual slluis.devel at gmail.com
Wed Mar 9 03:50:53 EST 2011


El dt 08 de 03 de 2011 a les 20:12 -0600, en/na Mike Kestner va
escriure:
> On Tue, Mar 8, 2011 at 5:22 PM, Christopher David Howie
> <me at chrishowie.com> wrote:
>  
>          -----------------------8<-----------------------
>             FooDialog d;
>             try {
>                 d = new FooDialog();
>                 d.Run();
>             } finally {
>                 if (d != null) {
>                     d.Destroy();
>                     d.Dispose();
>                 }
>             }
> 
> 
> The try/finally above accomplishes nothing.  The d.Run() call results
> in a native transition.  The only possible exception you can receive
> during that call would be related to an inability to pinvoke libgtk
> which presumably would have stopped you long before this point.  Once
> the transition to gtk_dialog_run has occurred, no exception
> propagation will or can come back across the native boundary.  Doing a
> Destroy would similarly fail pinvoke for any scenario regarding
> exceptions coming out of d.Run.  d != null fails for dialog
> constructor exceptions.  The Dispose call is redundant since Destroy
> calls Dispose.  I'm assuming this Destroy+Dispose pattern evolved from
> people writing Dispose, finding out they really needed to Destroy
> instead, and forgetting or not knowing they could remove the Dispose.
> 
> 
> The above code is therefore no more robust than:
> 
> 
> var d = new FooDialog ();
> d.Run ();
> d.Destroy ();
> 
> 
> The fact that people as knowledgable with Gtk# may be writing code
> like that though is a somewhat convincing argument that we have an
> opportunity to improve the binding here.

The above test case is a simplification of how things are usually done.
Just for reference, this is the full 'template':

     FooDialog d = null;
     try {
         d = new FooDialog();
	 [initialize d]
         if (d.Run() == DialogResult.Ok)
              [run Ok code]
         else
              [run Cancel code]
     } finally {
         if (d != null)
             d.Destroy();
     }

I often write initialization code after constructing the object, and
this code may throw an exception. In fact, it is better to use methods
to initialize the data that the dialog has to show rather than providing
that data in the constructor, since as you said an exception in the
constructor won't be catched and the dialog won't be destroyed.

On the other hand, code that checks the response of the dialog may throw
exceptions and must be executed before destroying the dialog (because it
may need to access data from widgets). So a try/catch is a must if you
want to be protected.

Lluis.



More information about the Gtk-sharp-list mailing list