Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 11 of 11
  1. #1
    Senior Coder alykins's Avatar
    Join Date
    Apr 2011
    Posts
    1,718
    Thanks
    41
    Thanked 191 Times in 190 Posts

    implements IDisposeable

    I am trying to incorporate IDisposable into a class I am making- but I am getting hung up on how to set the IntPtr. Does anyone know how to do this correctly?

    this is where my class is so far...
    Code:
    public class processTable : IDisposable
        {
    
            private IntPtr handle;
            private Component component = new Component();
            private bool disposed = false;
            
            private DataTable dt = new DataTable();
            private XHandle _XHandler = new XHandle();
            private string cName;
            private string pName;
            private string tblName;
            private colMap cm;
            private List<colMap> _Mappings = new List<colMap>();
    
            public processTable(DataTable _dt, IntPtr handle)
            {
                dt = _dt.Clone();
                tblName = dt.TableName;
                this.handle = handle;
            }
    
            private bool writeCols()
            {
                try
                {
                    for (int i = 0; i < dt.Columns.Count; i++)
                    {
                        cName = dt.Columns[i].ColumnName;
                        pName = string.Format("@{0}", cName);
                        cm = new colMap(i, cName, pName);
                        _Mappings.Add(cm);
                    }
                    Console.WriteLine("TableName:{0}", tblName);
                    foreach (colMap m in _Mappings)
                    {
                        Console.WriteLine("Order:{0}  Col:{1}  Param:{2}  Const:{3}", m._ColumnOrder, m._ColumnName, m._ParameterName, m._IsConstraint);
                    }
    
                    return true;
                }
                catch (Exception eX)
                {
                    _XHandler.XHandler(XHandle.XType.eX, eX);
                    return false;
                }
            }
    
            public void Dispose()
            {
                Dispose(true);
                GC.SuppressFinalize(this);
                throw new NotImplementedException();
            }
    
            protected virtual void Dispose(bool disposing)
            {
                if (!this.disposed)
                {
                    if (disposing)
                    {
                        component.Dispose();
                    }
                    CloseHandle(handle);
                    handle = IntPtr.Zero;
    
                    disposed = true;
                }
            }
    
            [System.Runtime.InteropServices.DllImport("Kernel32")]
            private extern static Boolean CloseHandle(IntPtr handle);
    
            ~processTable()
            {
                Dispose(false);
            }
        }
    and I want to be able to call it in a loop I have elsewhere...
    Code:
    private bool StepTableList()
            {
                processTable pt;
                SqlConnection conn;
                SqlDataAdapter da;
                DataTable tmpTbl;
                colMap cm;
                string cName;
                string pName;
    
                try
                {
                    foreach (string s in tblNameList)
                    {
                        tmpTbl = new DataTable();
                        conn = new SqlConnection(cnstr);
                        using (conn)
                        {
                            conn.Open();
                            da = new SqlDataAdapter(_QueryGetSchema.Replace("@XTable", s), conn);
                            using (da)
                            {
                                da.FillSchema(tmpTbl, SchemaType.Source);
                            }
                            conn.Close();
                        }
    
                        pt = new processTable(tmpTbl); // HERE!!!!
    
                    }
                }
    so since it is in that loop I would like to make it disposable- especially since it will get larger and more complex; but as you can see I need to determine where in memory I am going to create this, and how big... in short I need to do this as well in there...
    Code:
    IntPtr _intptr = new IntPtr();
    but I don't know how to do it correctly... Does anyone see what it is I am trying to do and 'how' to do it?

    I code C hash-tag .Net
    Reference: W3C W3CWiki .Net Lib
    Validate: html CSS
    Debug: Chrome FireFox IE

  • #2
    Rockstar Coder
    Join Date
    Jun 2002
    Location
    USA
    Posts
    9,074
    Thanks
    1
    Thanked 328 Times in 324 Posts
    I'm confused on what you are doing with the IntPtr to begin with. Are you trying to create a pointer to unmanaged memory?

    Other than the fact that you are always throwing the not implemented exception in your Dispose function, I don't see anything wrong.

    Why do you constantly open and close the connection to the database? It would be much more efficient to open it once outside of the foreach loop and then close it when the loop is done.
    OracleGuy

  • #3
    Senior Coder alykins's Avatar
    Join Date
    Apr 2011
    Posts
    1,718
    Thanks
    41
    Thanked 191 Times in 190 Posts
    the throw is the default template that gets put in there- it's what I need to change... I am opening the connection and hitting the db and pulling back info from INFORMATION_SCHEMA.TABLES and then going through each of those tables and processing them- I can't do it all in one connection because depending on the database the number of tables pulled will change- so the first call is to hit and get a set back.
    then that next nested connection loop is getting info from INFORMATION_SCHEMA.KEY_COLUMN_USAGE and processing that- so once again I can't do it all in one DB call...

    what I am *trying to do with the IntPtr is make my class disposable so I can dispose of it- I don't really know what to do with that part
    right now I am 'hacking' it and it is working...
    Code:
                processTable pt;
                SqlConnection conn;
                SqlDataAdapter da;
                DataTable tmpTbl;
                colMap cm;
                string cName;
                string pName;
    
                try
                {
                    foreach (string s in tblNameList)
                    {
                        tmpTbl = new DataTable();
                        conn = new SqlConnection(cnstr);
                        using (conn)
                        {
                            conn.Open();
                            da = new SqlDataAdapter(_QueryGetSchema.Replace("@XTable", s), conn);
                            using (da)
                            {
                                da.FillSchema(tmpTbl, SchemaType.Source);
                            }
                            conn.Close();
                        }
    
                        pt = new processTable(tmpTbl);
    
                    }
                    return true;
                }
    and so far I have not had any hiccups, but I would like to make it so I can dispose of it when I am done.

    Although- since it is in a foreach loop, is it already getting disposed?

    *thinking more about
    Why do you constantly open and close the connection to the database? It would be much more efficient to open it once outside of the foreach loop and then close it when the loop is done.
    ... I guess I could hit the info tables once and fill a set- I'll work on changing that- thanks for insight...

    I still though am stuck on the pointer- do I need to make it? my understanding is you define the pointer to be *this big and it is going to go *here and then that allows it to be managed and thus disposable...

    am I understanding that wrong?

    Edit:
    make it so I can do this...
    Code:
                               da.FillSchema(tmpTbl, SchemaType.Source);
                            }
                            conn.Close();
                        }
    
                        pt = new processTable(tmpTbl);
                        using (pt)
                        {
                                  // TODO
                        }
    
                    }
                    return true;
                }
    Last edited by alykins; 05-13-2012 at 07:58 PM.

    I code C hash-tag .Net
    Reference: W3C W3CWiki .Net Lib
    Validate: html CSS
    Debug: Chrome FireFox IE

  • #4
    Rockstar Coder
    Join Date
    Jun 2002
    Location
    USA
    Posts
    9,074
    Thanks
    1
    Thanked 328 Times in 324 Posts
    Oh OK I think I understand your confusion with the pointer. If your class isn't going to be using any unmanaged resources (aka memory or handles) then you don't need to implement that interface. The objects you create in that loop will automatically be deleted once there are no more references to the object the next time the runtime does garbage collection. That means you don't need that IntPtr at all.

    That example on the MSDN that uses the IntPtr is if you were working with unmanaged code and were actually creating unmanaged memory from a managed object.

    The tl;dr version: The IDisposable interface isn't needed for what you are doing.

    As for the database connection, even if you don't get all the data you need in one query why can't you re-use the same connection for multiple queries if the connection details aren't changing? That was what I was getting at.
    OracleGuy

  • Users who have thanked oracleguy for this post:

    alykins (05-14-2012)

  • #5
    Senior Coder alykins's Avatar
    Join Date
    Apr 2011
    Posts
    1,718
    Thanks
    41
    Thanked 191 Times in 190 Posts
    so how would I implement the disposable then? the MSDN example calls out using the pointer- yes I think what you are saying is exactly the 'issue' I am having- I will be managing it by explicitly disposing it, but I can't dispose it without making it disposable which in turn uses that example... so do I just set the pointer to be null ref? or zero ref?

    when you do the 'tab tab' to 'auto generate' the disposeable block it gives you this...
    Code:
            public void Dispose()
            {
                throw new NotImplementedException();
            }
    so that is how I got to 'where' I am now- I was trying to figure out 'what' to do there- the example MSDN lead me down the other path.... how do I just implement it without all the 'extra' MSDN stuff?

    the connection I am using over and over...
    but if I do this...
    Code:
    SqlConnection conn = new SqlConnection(cnstr);
    for(int i=0; i< number; i++;)
    {
      using (conn)
      {
       conn.Open();
           blah blah blah
       conn.Close();
       }
    }
    the second trip through that loop the conn got disposed and now will throw a null exception correct?

    I thought doing this...
    Code:
    SqlConnection conn;
    
    for(int i=0; i < number; i++)
    {
      conn = new SqlConnection(cnstr);
      using(conn)
      {
        conn.Open();
          blah blah blah
        conn.Close();
       }
    }
    was a 'best practice' ... am I wrong on that? moreover am I wrong on that the first code block would throw a null exception on the second trip through (I thought it did)?


    tldr;
    if you are referring to mine, yeah, there is a lot of code there posted- and it is hard to gauge 'how much code' to post- bc sometimes you post a lot trying to ask a specific Q and the replies are 'want to see all code' so yeah....

    for now I agree, I don't need to implement that interface, but while the class is small and manageable I am trying to learn/figure out how to do so- so as it grows, or classes I create in the future that do need to be disposable I will know it-
    the problem is most ppl whom I've asked either don't know, haven't done it in years and don't remember, or some other comment along those lines... so I'm left to trying to figure it our... my C# ref texts don't go into details about it either

    if the tldr; is WRT MSDN,
    I really get frustrated sometimes with their 'explanations'... def is my 'go-to' place for anything I need to look up, but the second you step into something more complex, there are no practical examples, and their code comment's are sometimes cryptic and sometimes reference other code blocks they don't explicitly call out (ie you have to know where to look to find the code block they are referring to)

    anyways thanx for your help so far

    I code C hash-tag .Net
    Reference: W3C W3CWiki .Net Lib
    Validate: html CSS
    Debug: Chrome FireFox IE

  • #6
    Rockstar Coder
    Join Date
    Jun 2002
    Location
    USA
    Posts
    9,074
    Thanks
    1
    Thanked 328 Times in 324 Posts
    Quote Originally Posted by alykins View Post
    so how would I implement the disposable then? the MSDN example calls out using the pointer- yes I think what you are saying is exactly the 'issue' I am having- I will be managing it by explicitly disposing it, but I can't dispose it without making it disposable which in turn uses that example... so do I just set the pointer to be null ref? or zero ref?
    My point was you don't need to implement it at all. That interface is for something which you aren't doing. It doesn't matter how big your class gets unless you are working with unmanaged resources, you don't need IDisposable. If you were using unmanaged resources then you would have something to set IntPtr to since it would point to said resources.

    Quote Originally Posted by alykins View Post
    the connection I am using over and over...
    but if I do this...
    Code:
    SqlConnection conn = new SqlConnection(cnstr);
    for(int i=0; i< number; i++;)
    {
      using (conn)
      {
       conn.Open();
           blah blah blah
       conn.Close();
       }
    }
    the second trip through that loop the conn got disposed and now will throw a null exception correct?

    I thought doing this...
    Code:
    SqlConnection conn;
    
    for(int i=0; i < number; i++)
    {
      conn = new SqlConnection(cnstr);
      using(conn)
      {
        conn.Open();
          blah blah blah
        conn.Close();
       }
    }
    was a 'best practice' ... am I wrong on that? moreover am I wrong on that the first code block would throw a null exception on the second trip through (I thought it did)?
    I would do it like this:

    Code:
    SqlConnection conn = new SqlConnection(cnstr);
    conn.Open();
    for(int i=0; i< number; i++;)
    {
           blah blah blah
    }
    conn.Close();
    Quote Originally Posted by alykins View Post
    if you are referring to mine, yeah, there is a lot of code there posted- and it is hard to gauge 'how much code' to post- bc sometimes you post a lot trying to ask a specific Q and the replies are 'want to see all code' so yeah....
    Actually I was referring to my post. I was just summarizing what I had said.

    Quote Originally Posted by alykins View Post
    for now I agree, I don't need to implement that interface, but while the class is small and manageable I am trying to learn/figure out how to do so- so as it grows, or classes I create in the future that do need to be disposable I will know it-
    the problem is most ppl whom I've asked either don't know, haven't done it in years and don't remember, or some other comment along those lines... so I'm left to trying to figure it our... my C# ref texts don't go into details about it either
    The size of the class doesn't matter, the garbage collection will handle it all the same. IDisposable doesn't save memory per-se it is just a way to clean up the resources of a class before the destructor fires. Which isn't necessary in most cases because you could just do it in the destructor.

    One of the main uses for IDisposable is if your application works with unmanaged code. Such as if your C# application calls into a C++ DLL directly. That isn't something that is done too often which is why a lot of people don't know much about it.

    Hopefully I'm making sense.
    OracleGuy

  • #7
    Senior Coder alykins's Avatar
    Join Date
    Apr 2011
    Posts
    1,718
    Thanks
    41
    Thanked 191 Times in 190 Posts
    Quote Originally Posted by oracleguy View Post
    One of the main uses for IDisposable is if your application works with unmanaged code. Such as if your C# application calls into a C++ DLL directly. That isn't something that is done too often which is why a lot of people don't know much about it.

    Hopefully I'm making sense.
    you are, a lot that is the problem I think though in that it is hard to find someone who 'really' knows how/why/when to use it- I guess a downfall of evolving code.

    do you know of any code snips that create a class using a C++ dll or something of that nature that I would need to 'know' ... I like to figure out/learn all I can- also I am looking to start tinkering with netduino and get back into the world of PICS- I think that I may end up needed it when I start referencing the lower layers (or maybe I am still off lol)

    point being- I would like to see a class made that implements it, and does so correctly so I can extrapolate when/how/why more effectively. But as you said not a lot of ppl know/understand it and it is hard to find clear-cut answers.

    as for the SQLConn... I usually wrap it up in the using clause to ensure it gets destroyed and holds no open sessions... do you think that is not so much necessary for SQL conns?
    do you think something like this is more applicable?
    Code:
    private DataSet XSet = new DataSet();
    .....
    private bool fillSet()
    {
    DataTable dt;
    SqlCommand cmd;
    
    SqlConnection conn = new SqlConnection(cnstr);
    using(conn)
    {
      conn.Open();
      foreach(string s in tblList)
      {
       cmd = new SqlCommand("select * from " + s, conn);
       cmd.CommandType = CommandType.Text;
       using(cmd)
       {
         SqlDatareader dr = cmd.ExecuteReader();
         dt = new DataTable();
         dt.Load(dr);
         dt.TableName = s
         XSet.Tables.Add(dt);
         dt.Dispose();
       }
       cmd.Dispose();
    }
    return true;
    }
    or do you think that is overkill on disposal?
    Note* I did it all free-hand so syntax'es may be off and what-not

    so that's where I am thinking of implementing the disposal- I know (or at least think I know correctly) that if you encapsulate an object inside another object and the parent object is disposed then the child will in turn be disposed (the parent cannot be disposed of until the child is) so wrapping any class inside a disposing loop would in turn dispose of that object- right?

    but when does too much become too much? is what I have 'too much'? where does the performance hit really 'hit'? and then when you step into the world of threads you have to ensure that nothing is stepping on anything else's toes- so, like locks aside, would what I have there 'help' in keeping threadsafe? or does it not really matter?

    -- maybe move this to a forum lounge thread (or spwan a thread in there to keep the integrity of the original post's in this)? becoming more of an internal C# workings and stack thread

    I code C hash-tag .Net
    Reference: W3C W3CWiki .Net Lib
    Validate: html CSS
    Debug: Chrome FireFox IE

  • #8
    Rockstar Coder
    Join Date
    Jun 2002
    Location
    USA
    Posts
    9,074
    Thanks
    1
    Thanked 328 Times in 324 Posts
    I haven't forgot about your thread, I've just been really busy. I'll try to answer your questions later this week. I was going to make an example of when you'd actually need to use that interface.
    OracleGuy

  • Users who have thanked oracleguy for this post:

    alykins (05-16-2012)

  • #9
    Senior Coder alykins's Avatar
    Join Date
    Apr 2011
    Posts
    1,718
    Thanks
    41
    Thanked 191 Times in 190 Posts
    kk thanx
    I really do appreciate your help- I did not learn C# in a 'traditional' setting. I have a BSEE and learned assembly and PLC languages... From there I evolved in my professional career but in short- no formal college classes. Wrox, MSDN class library, practice, and practical application (both inside work and outside) have been my life for quite some time

    I code C hash-tag .Net
    Reference: W3C W3CWiki .Net Lib
    Validate: html CSS
    Debug: Chrome FireFox IE

  • #10
    Rockstar Coder
    Join Date
    Jun 2002
    Location
    USA
    Posts
    9,074
    Thanks
    1
    Thanked 328 Times in 324 Posts
    Dug this out of my bookmarks: http://stackoverflow.com/questions/5...able-interface Read the first answer, it is pretty long but is a great explanation of the interface.
    OracleGuy

  • Users who have thanked oracleguy for this post:

    alykins (05-21-2012)

  • #11
    Senior Coder alykins's Avatar
    Join Date
    Apr 2011
    Posts
    1,718
    Thanks
    41
    Thanked 191 Times in 190 Posts
    thanks for that I will have to read on my free time- pretty swamped ATM- will add to 'todo' list

    I code C hash-tag .Net
    Reference: W3C W3CWiki .Net Lib
    Validate: html CSS
    Debug: Chrome FireFox IE


  •  

    Tags for this Thread

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •