Wrox Programmer Forums
|
BOOK: ASP.NET Website Programming Problem-Design-Solution
This is the forum to discuss the Wrox book ASP.NET Website Programming: Problem - Design - Solution, Visual Basic .NET Edition by Marco Bellinaso, Kevin Hoffman; ISBN: 9780764543869
Welcome to the p2p.wrox.com Forums.

You are currently viewing the BOOK: ASP.NET Website Programming Problem-Design-Solution section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old March 27th, 2004, 10:31 PM
Authorized User
 
Join Date: Mar 2004
Posts: 12
Thanks: 0
Thanked 0 Times in 0 Posts
Default C# using statement

I love the book, but I don't understand how code like this can work successfully.

public DataSet GetRoleList()
{
  using (DataSet roles = SomeMethod{))
  {
    return roles;
  }
}

Isn't roles disposed as soon as scope leaves the using block? According to various documentation I've run across this generates IL that is exactly equivalent to disposing roles in a finally block.

If coded correctly, the returned reference to roles should throw an "already disposed" exception when accessed by the caller it was returned to. I guess if it doesn't, then it will still work until the Garbage Collector claims it, which won't happen until the calling codes reference becomes unreachable, in which case, what's the point of returning it from within a using block.

Richard Waddell




 
Old March 30th, 2004, 02:58 AM
Authorized User
 
Join Date: Mar 2004
Posts: 33
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Well, I don't know C#, but if what you say is write then it sounds like you have a good point.
If it helps, here's the VB code for that function in Role.vb in Accounts.Data

    Public Function GetRoleList() As DataSet

      Dim roles As DataSet
      Try
        roles = RunProcedure( _
          "sp_Accounts_GetAllRoles", New IDataParameter() {}, "Roles")
        Return roles
      Finally
        If Not roles Is Nothing Then
          roles.Dispose()
        End If
      End Try

    End Function

 
Old April 7th, 2004, 09:55 PM
Friend of Wrox
 
Join Date: Jun 2003
Posts: 917
Thanks: 0
Thanked 0 Times in 0 Posts
Default

It doesn't look wrong to me. It's passing back the DataSet as the return value of the function. Once it gets assigned by the return statement you don't need "roles" anymore.
 
Old April 9th, 2004, 01:53 AM
Authorized User
 
Join Date: Mar 2004
Posts: 12
Thanks: 0
Thanked 0 Times in 0 Posts
Default

But roles is a reference item, which means it points to an object on the heap. The reference that it returns points to the same object, so dispose called on roles is the same as calling dispose on the returned object.

I wrote some test code to prove it one way or another.

(1)
The following class, 'FormImage' supports a single function, ShowImage(), which paints a bitmap on a form at a specified location. It uses a bitmap resource which it releases when Dispose()is called.

(2)
The function CreateFormImageObject creates a FormImage object in
a using statement and returns it to the caller from within the using block. To demonstrate that the object works at this point I call ShowImage() from within the using block before the FormImage object
is returned.

(3)
In the FormImage Dispose method, I show a MessageBox to demonstrate that the Dispose method is called when the using block goes out of scope.

(4)
The whole process is started off by a button click event handler which calls CreateFormImageObject() and then calls ShowImage on the returned object.

The result was that ShowImage showed a message box stating the object was already disposed. ShowImage allows the code to continue, which results in a NullReference exception because the bitmap was set to null when Dispose was called previously.

Note, in the Dispose method, if you comment out m_bmp.Dispose and m_bmp = null, then ShowImage will continue to work fine. Probably the same thing is happening in the book code when the DataSet is being disposed - Dispose really isn't releasing anything, so the methods continue to work.

In a real-world scenario both my code and DataSet should throw an 'AlreadyDisposed' exception when any method is invoked after Dispose has already been called. And of course my code should have a Finalize method (Destructor).

I hope this code isn't too mangled. If so, and you're interested, send me your email address.

// Here's the FormImage class
public class FormImage : IDisposable
{
     private bool m_bDisposed;
     private Form m_frm;
     private Bitmap m_bmp;

     public FormImage(Form frm)
     {
          m_bDisposed = false;
          m_frm = frm;
          m_bmp = new Bitmap(100, 100);
          Graphics gr = Graphics.FromImage(m_bmp);
          gr.FillRectangle(Brushes.Red, 0, 0, m_bmp.Width, m_bmp.Height);
          gr.DrawRectangle(Pens.Black, 10, 10, m_bmp.Width - 20, m_bmp.Height -20);
          gr.Dispose();
     }

     public void ShowImage(int x, int y)
     {
          if (m_bDisposed)
          {
             MessageBox.Show("ShowImage: AlreadyDisposed");
          }
          Graphics gr = m_frm.CreateGraphics();
          gr.DrawImage(m_bmp, new Rectangle(x, y, m_bmp.Width, m_bmp.Height));
          gr.Dispose();
     }

     public void Dispose()
     {
          if (m_bDisposed)
          {
              MessageBox.Show("Dispose: Already Disposed");
              return;
          }
          MessageBox.Show("Disposing");
          if (m_bmp != null)
          {
             m_bmp.Dispose();
             m_bmp = null;
          }
          m_bDisposed = true;
      }
}

// Call this function to create a form image and return
// it from within a using block
private FormImage CreateFormImageObject()
{
     using (FormImage objShow = new FormImage(this))
     {
          MessageBox.Show("Calling ShowImage from within using block");
          objShow.ShowImage(10, 10);
          return objShow;
      }
}

// This code calls CreateFormImageObject and then tries to
// call a method on the object to demonstrate that the object
// has already been disposed when it is returned from CreateFormImageObject
private void btnTest_Click(object sender, System.EventArgs e)
{
     FormImage objShow = CreateFormImageObject();
     MessageBox.Show("Calling ShowImage after return from CreateFormImageObject");
     objShow.ShowImage(100, 100);
}


 
Old April 9th, 2004, 03:55 PM
Friend of Wrox
 
Join Date: Jun 2003
Posts: 917
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Sorry, you're right. I wasn't thinking clearly. It's a reference type and no matter how many references it has, it will be disposed for all of them if any one of them disposes it.





Similar Threads
Thread Thread Starter Forum Replies Last Post
if/else statement mussa Beginning PHP 5 July 3rd, 2006 06:06 PM
What does the @ do in the following statement? kenn_rosie VB.NET 2002/2003 Basics 1 March 15th, 2006 12:20 PM
Like Statement Nitin_sharma Oracle ASP 2 May 10th, 2005 12:18 AM
Like Statement Nitin_sharma Oracle 4 February 12th, 2005 01:46 PM
Like statement Nitin_sharma Classic ASP Databases 7 February 1st, 2005 11:12 AM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.