[fdo-users] .net Wrapper quirks

Romica Dascalescu Romica.Dascalescu at autodesk.com
Sat Nov 1 14:35:42 EDT 2008


Hi Jackie,

First I would avoid calling FDO_object.Dispose();
Now try using "using" with FDO objects you will be sure the object is released after is used.
I modified your file, try it and see if you still get the crash.

Regards
Romy.
________________________________________
From: fdo-users-bounces at lists.osgeo.org [fdo-users-bounces at lists.osgeo.org] On Behalf Of Jackie C. Ng [jumpinjackie at gmail.com]
Sent: Saturday, November 01, 2008 1:44 AM
To: fdo-users at lists.osgeo.org
Subject: RE: [fdo-users] .net Wrapper quirks

I'll cite a more concrete example:

http://code.google.com/p/fdotoolbox/source/browse/sandbox/FdoToolbox.Lib/Controls/GenericSpatialConnectCtl.cs#220

This code builds the grid cells to allow you to enter the connection
properties. Using the latest FDO trunk, if the provider is OGR, then once
the method has completed, the application will die (with
System.AccessViolation) if you switch (alt-tab) to another application and
back in.

With pdbs, the error message becomes:

Unhandled exception at 0x0522f116 in FdoToolbox.exe: 0xC0000005: Access
violation reading location 0xfeeefefa.

With the point of failure being at:
OSGeo::FDO::Connections::IConnectionPropertyDictionaryImp::ReleaseUnmanagedObject()

Now if I were to disable the using block on the connection that gets created
(ie. Don't Dispose() the connection), I no longer get this access violation!

Hence the Dispose() or no? question. I am confused.

- Jackie


Donald Cameron wrote:
>
> I find my code throws exceptions on termination if I don't dispose of any
> readers I have created during its execution.
>
> Don
>
> -----Original Message-----
> From: fdo-users-bounces at lists.osgeo.org
> [mailto:fdo-users-bounces at lists.osgeo.org] On Behalf Of Jackie C. Ng
> Sent: Friday, October 31, 2008 8:56 AM
> To: fdo-users at lists.osgeo.org
> Subject: RE: [fdo-users] .net Wrapper quirks
>
>
> Sorry to necro this discussion but it seems the dreaded
> System.AccessViolationException has reared its ugly head again in my
> testing
> of FDO Toolbox with the PostGIS and OGR providers (I'm testing on the
> trunk
> build of FDO). I guess I need clarification on the following matters:
>
> 1 - Dispose() or no? Should I just be letting the GC do its job. Could I
> be
> screwing up reference counts by Disposing objects myself, thus possibly
> causing these errors?
>
> 2 - The devguide states that method chaining is bad. Does this still apply
> with the managed wrappers?
>
> - Jackie
>
>
> gregboone wrote:
>>
>> This is the primary cause of the defect as it results in an excessive
>> number of SQLite resources being instantiated and used before enough
>> resources are freed by the garbage collector. As a work-around, calling
>> Close()/Dispose() should resolve the issue. However, we will also try and
>> make a fix in the SDF provider so that these steps are not explicitly
>> necessary.
>>
>> One last point, you still should explicitly assign the result of Execute
>> to a Feature Reader so that the garbage collection can happen at an
>> appropriate time.
>>
>> Greg
>>
>> -----Original Message-----
>> From: fdo-users-bounces at lists.osgeo.org
>> [mailto:fdo-users-bounces at lists.osgeo.org] On Behalf Of Jackie Ng
>> Sent: Friday, April 04, 2008 2:38 AM
>> To: fdo-users at lists.osgeo.org
>> Subject: Re: [fdo-users] .net Wrapper quirks
>>
>>
>> I just looked at the unit test code for the ticket, and noticed I might
>> have
>> been doing something wrong.
>>
>> I forgot that IInsert::Execute() returns an IFeatureReader and so I
>> haven't
>> been closing and disposing them.
>>
>> One (of many?) possible cause(s)?
>>
>> - Jackie
>>
>>
>> Jackie Ng wrote:
>>>
>>> Hi All,
>>>
>>> I've been writing .net code that copies data from one FDO connection to
>>> another (Doing a series of IInsert::Execute() calls from an
>>> IFeatureReader
>>> ). In my adventures using the FDO .net wrapper, I have encountered the
>>> following problems at random:
>>>
>>> - System.AccessViolationExceptions ("Attempted to read or write
>>> protected
>>> memory. This is often an indication that other memory is corrupt")
>>> thrown
>>> at OSGeo.FDO.Runtime.Disposable.Finalize() (Target Site: void
>>> ReleaseUnmanagedObject() )
>>> - C++ pure virtual function call errors.
>>> - Memory allocation failed errors.
>>>
>>> Is there some quirks with the .net wrapper that I should be aware of? As
>>> OSGeo.FDO.Runtime.Disposable implements IDisposable, I've been wrapping
>>> nearly every FDO object used inside using() blocks. Could this be a
>>> cause?
>>>
>>> I am using .net wrappers for FDO 3.3.0
>>>
>>> - Jackie
>>>
>>>
>>>
>>
>> --
>> View this message in context:
>> http://www.nabble.com/.net-Wrapper-quirks-tp16318694s18162p16485877.html
>> Sent from the fdo-users mailing list archive at Nabble.com.
>>
>> _______________________________________________
>> fdo-users mailing list
>> fdo-users at lists.osgeo.org
>> http://lists.osgeo.org/mailman/listinfo/fdo-users
>> _______________________________________________
>> fdo-users mailing list
>> fdo-users at lists.osgeo.org
>> http://lists.osgeo.org/mailman/listinfo/fdo-users
>>
>>
>
>
> -----
> http://themapguyde.blogspot.com
>
> http://www.linkedin.com/in/jackieng
> --
> View this message in context:
> http://www.nabble.com/.net-Wrapper-quirks-tp16318694p20265376.html
> Sent from the FDO Users mailing list archive at Nabble.com.
>
> _______________________________________________
> fdo-users mailing list
> fdo-users at lists.osgeo.org
> http://lists.osgeo.org/mailman/listinfo/fdo-users
> _______________________________________________
> fdo-users mailing list
> fdo-users at lists.osgeo.org
> http://lists.osgeo.org/mailman/listinfo/fdo-users
>
>


-----
http://themapguyde.blogspot.com

http://www.linkedin.com/in/jackieng
--
View this message in context: http://www.nabble.com/.net-Wrapper-quirks-tp16318694p20277762.html
Sent from the FDO Users mailing list archive at Nabble.com.

_______________________________________________
fdo-users mailing list
fdo-users at lists.osgeo.org
http://lists.osgeo.org/mailman/listinfo/fdo-users
-------------- next part --------------
#region LGPL Header
// Copyright (C) 2008, Jackie Ng
// http://code.google.com/p/fdotoolbox, jumpinjackie at gmail.com
// 
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
// 
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
// 
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
// 
#endregion
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using OSGeo.FDO.ClientServices;
using System.Collections.Specialized;
using OSGeo.FDO.Connections;
using OSGeo.FDO;
using FdoToolbox.Lib.Forms;
using FdoToolbox.Lib.ClientServices;
using FdoToolbox.Core.ClientServices;

namespace FdoToolbox.Lib.Controls
{
    public partial class GenericSpatialConnectCtl : BaseDocumentCtl
    {
        public GenericSpatialConnectCtl()
        {
            InitializeComponent();
            InitializeGrid();
            this.Title = "New Data Connection";
            _PendingProperties = new List<string>();
            StringCollection providerNames = new StringCollection();
            using (IProviderRegistry provReg = FeatureAccessManager.GetProviderRegistry())
            {
                using (ProviderCollection providers = provReg.GetProviders())
                {
                    foreach (OSGeo.FDO.ClientServices.Provider prov in providers)
                    {
                        using (prov)
                        {
                            providerNames.Add(prov.Name);
                        }
                    }
                }
            }
            cmbProvider.DataSource = providerNames;
        }

        private string ParseConnectionString()
        {
            string str = "";
            foreach (DataGridViewRow row in grdConnectProperties.Rows)
            {
                if (row.Cells[1].Value != null && !string.IsNullOrEmpty(row.Cells[1].Value.ToString()))
                {
                    if (string.IsNullOrEmpty(str))
                        str += string.Format("{0}={1}", row.Cells[0].Value, row.Cells[1].Value);
                    else
                        str += string.Format(";{0}={1}", row.Cells[0].Value, row.Cells[1].Value);
                }
            }
            return str;
        }

        private void cmbProvider_SelectedIndexChanged(object sender, EventArgs e)
        {
            SetConnectProperties(cmbProvider.SelectedItem.ToString());
        }

        private void btnTest_Click(object sender, EventArgs e)
        {
            using (IConnectionManager connMan = FeatureAccessManager.GetConnectionManager())
            {
                using (IConnection conn = connMan.CreateConnection(cmbProvider.SelectedItem.ToString()))
                {
                    conn.ConnectionString = this.ParseConnectionString();
                    try
                    {
                        if (conn.Open() == OSGeo.FDO.Connections.ConnectionState.ConnectionState_Open)
                        {
                            MessageBox.Show("Connection Successful");
                            conn.Close();
                        }
                        else
                            MessageBox.Show("Connection failed");
                    }
                    catch (OSGeo.FDO.Common.Exception ex)
                    {
                        MessageBox.Show("Connection failed: " + ex.Message);
                    }
                }
            }
        }
        private void btnConnect_Click(object sender, EventArgs e)
        {
            errorProvider1.Clear();
            if (string.IsNullOrEmpty(txtName.Text))
            {
                errorProvider1.SetError(txtName, "Required");
                return;
            }
            if (AppGateway.RunningApplication.FdoConnectionManager.GetConnection(txtName.Text) != null)
            {
                errorProvider1.SetError(txtName, "The specified connection name already exists. Please choose another");
                return;
            }
            using (IConnectionManager connMan = FeatureAccessManager.GetConnectionManager())
            {
                using (IConnection conn = connMan.CreateConnection(cmbProvider.SelectedItem.ToString()))
                {
                    conn.ConnectionString = this.ParseConnectionString();
                    try
                    {
                        if (conn.Open() == OSGeo.FDO.Connections.ConnectionState.ConnectionState_Pending)
                        {
                            //Pending. Further parameters required
                            NameValueCollection pendingParams = PendingParameterDialog.GetParameters(_PendingProperties, conn);
                            if (pendingParams != null)
                            {
                                using (IConnectionInfo connInfo = conn.ConnectionInfo)
                                {
                                    using (IConnectionPropertyDictionary connProps = connInfo.ConnectionProperties)
                                    {
                                        foreach (string name in pendingParams.AllKeys)
                                        {
                                            connProps.SetProperty(name, pendingParams[name]);
                                        }
                                    }
                                }
                            }
                            else
                            {
                                throw new FdoConnectionException("Pending Parameters were not filled in");
                            }
                        }
                        if (conn.ConnectionState == OSGeo.FDO.Connections.ConnectionState.ConnectionState_Open || conn.Open() == OSGeo.FDO.Connections.ConnectionState.ConnectionState_Open)
                        {
                            AppGateway.RunningApplication.FdoConnectionManager.AddConnection(txtName.Text, conn);
                            this.Close();
                        }
                        else
                        {
                            throw new FdoConnectionException("Opening the connection did not move it to the \"opened\" state");
                        }
                    }
                    catch (FdoConnectionException ex)
                    {
                        AppConsole.Alert("Error", ex.Message);
                        conn.Close();
                    }
                    catch (OSGeo.FDO.Common.Exception ex)
                    {
                        AppConsole.Alert("Error", "Connection failed: " + ex.Message);
                        conn.Close();
                    }
                }
            }
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void InitializeGrid()
        {
            grdConnectProperties.Rows.Clear();
            grdConnectProperties.Columns.Clear();
            DataGridViewColumn colName = new DataGridViewColumn();
            colName.Name = "COL_NAME";
            colName.HeaderText = "Name";
            colName.ReadOnly = true;
            DataGridViewColumn colValue = new DataGridViewColumn();
            colValue.Name = "COL_VALUE";
            colValue.HeaderText = "Value";

            colValue.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
            grdConnectProperties.Columns.Add(colName);
            grdConnectProperties.Columns.Add(colValue);
        }

        private DataGridViewRow AddRequiredProperty(string name, string defaultValue)
        {
            //TODO: Attach a validation scheme
            return AddProperty(name, defaultValue);
        }

        private DataGridViewRow AddRequiredEnumerableProperty(string name, string defaultValue, IEnumerable<string> values)
        {
            //TODO: Attach a validation scheme
            return AddOptionalEnumerableProperty(name, defaultValue, values);
        }

        private DataGridViewRow AddOptionalEnumerableProperty(string name, string defaultValue, IEnumerable<string> values)
        {
            DataGridViewRow row = new DataGridViewRow();
            DataGridViewTextBoxCell nameCell = new DataGridViewTextBoxCell();
            nameCell.Value = name;
            DataGridViewComboBoxCell valueCell = new DataGridViewComboBoxCell();
            valueCell.DataSource = values;
            valueCell.Value = defaultValue;
            row.Cells.Add(nameCell);
            row.Cells.Add(valueCell);

            grdConnectProperties.Rows.Add(row);
            return row;
        }

        private DataGridViewRow AddProperty(string name, string defaultValue)
        {
            DataGridViewRow row = new DataGridViewRow();
            DataGridViewTextBoxCell nameCell = new DataGridViewTextBoxCell();
            nameCell.Value = name;
            DataGridViewTextBoxCell valueCell = new DataGridViewTextBoxCell();
            valueCell.Value = defaultValue;
            row.Cells.Add(nameCell);
            row.Cells.Add(valueCell);

            grdConnectProperties.Rows.Add(row);
            return row;
        }

        private List<string> _PendingProperties;

        public void SetConnectProperties(string provider)
        {
            _PendingProperties.Clear();
            try
            {
                using (IConnectionManager connMan = FeatureAccessManager.GetConnectionManager())
                {
                    using (IConnection conn = connMan.CreateConnection(provider))
                    {
                        using (IConnectionInfo connInfo = conn.ConnectionInfo)
                        {
                            using (IConnectionPropertyDictionary connProps = connInfo.ConnectionProperties)
                            {
                                string[] propertyNames = connProps.PropertyNames;
                                grdConnectProperties.Rows.Clear();
                                foreach (string name in propertyNames)
                                {
                                    string localized = connProps.GetLocalizedName(name);
                                    bool required = connProps.IsPropertyRequired(name);
                                    bool enumerable = connProps.IsPropertyEnumerable(name);
                                    string defaultValue = connProps.GetPropertyDefault(name);
                                    if (enumerable)
                                    {
                                        bool canGetValues = true;
                                        string[] values = null;
                                        try
                                        {
                                            values = connProps.EnumeratePropertyValues(name);
                                        }
                                        catch
                                        {
                                            _PendingProperties.Add(name);
                                            canGetValues = false;
                                        }
                                        if (canGetValues)
                                        {
                                            if (required)
                                            {
                                                DataGridViewRow row = AddRequiredEnumerableProperty(localized, defaultValue, values);
                                                if (values.Length > 0)
                                                    row.Cells[1].Value = values[0];
                                            }
                                            else
                                            {
                                                AddOptionalEnumerableProperty(localized, defaultValue, values);
                                            }
                                        }
                                    }
                                    else
                                    {
                                        if (required)
                                        {
                                            AddRequiredProperty(localized, defaultValue);
                                        }
                                        else
                                        {
                                            AddProperty(localized, defaultValue);
                                        }
                                    }
                                }
                                btnTest.Enabled = btnConnect.Enabled = true;
                            }
                        }
                    }
                }
            }
            catch (OSGeo.FDO.Common.Exception ex)
            {
                AppConsole.Alert("Error", ex.Message);
                btnTest.Enabled = btnConnect.Enabled = false;
                grdConnectProperties.Rows.Clear();
            }
        }
    }
}



More information about the fdo-users mailing list