-2

I got this error and I don't know what I doing wrong. The code below is in the backrgoundworker.

Copy exception detail to the clipboard :

System.Runtime.InteropServices.InvalidComObjectException was unhandled by user code HResult=-2146233049 Message=COM object that has been separated from its underlying RCW cannot be used. Source=mscorlib
StackTrace: at System.StubHelpers.StubHelpers.StubRegisterRCW(Object pThis) at System.Data.Common.UnsafeNativeMethods.IAccessor.ReleaseAccessor(IntPtr hAccessor, Int32& pcRefCount) at System.Data.OleDb.RowBinding.Dispose() at System.Data.OleDb.OleDbCommand.ResetConnection() at System.Data.OleDb.OleDbCommand.Dispose(Boolean disposing) at System.ComponentModel.Component.Dispose() at AttendanceSystem.Student.frmNewStudent.bgwInsertStudent_DoWork(Object sender, DoWorkEventArgs e) in c:\Users\victorbaccaljr\Desktop\PROGRAM\Event Attendace System\AttendanceSystem\AttendanceSystem\Student\frmNewStudent.cs:line 138 at System.ComponentModel.BackgroundWorker.OnDoWork(DoWorkEventArgs e) at System.ComponentModel.BackgroundWorker.WorkerThreadStart(Object argument) InnerException:

code :

private void bgwInsertStudent_DoWork(object sender, DoWorkEventArgs e)
    {
        List<object> arg = (List<object>)e.Argument;
        bool found = false;
         using (OleDbConnection cnn = new OleDbConnection(ConfigurationManager.ConnectionStrings["db"].ConnectionString))
        {
            using (OleDbCommand cmd = new OleDbCommand())
            {
                cmd.CommandText = "select top 1 * from [student info] where id=@id";
                cmd.Connection = cnn;

                cmd.Parameters.Clear();
                cmd.Parameters.AddWithValue("@id", arg[0].ToString());

                cnn.Open();
                using (OleDbDataReader rdr = cmd.ExecuteReader())
                {
                    rdr.Read();
                    if (rdr.HasRows)
                    {
                        found = true;
                    }
                    cnn.Close();
                }
            }
            using(OleDbCommand cmd=new OleDbCommand())
            {
                if(found)
                {
                    MessageBox.Show("Student ID already inserted.");
                }
                else
                {
                    cmd.CommandText = "insert into [Student info] values(@id, @firstname, @lastname, @department, @address)";
                    cmd.Connection = cnn;

                    cmd.Parameters.Clear();
                    cmd.Parameters.AddWithValue("@id", arg[0].ToString());
                    cmd.Parameters.AddWithValue("@firstname", arg[1].ToString());
                    cmd.Parameters.AddWithValue("@lastname", arg[2].ToString());
                    cmd.Parameters.AddWithValue("@department", arg[3].ToString());
                    cmd.Parameters.AddWithValue("@address", arg[4].ToString());

                    cnn.Open();
                    cmd.ExecuteNonQuery();
                    cnn.Close();

                    MessageBox.Show("Record inserted!");

                    this.DialogResult = DialogResult.OK;

                }
            }
        }
    }
MakePeaceGreatAgain
  • 35,491
  • 6
  • 60
  • 111
Vic
  • 457
  • 1
  • 6
  • 23
  • 2
    Do not call `cnn.Close()` – ASpirin Sep 28 '17 at 06:42
  • And please post the actual code within your question, don´t use images as it´s impossible to find them in the search-engines. – MakePeaceGreatAgain Sep 28 '17 at 06:42
  • 3
    Possible duplicate of [COM object that has been separated from its underlying RCW cannot be used](https://stackoverflow.com/questions/2260990/com-object-that-has-been-separated-from-its-underlying-rcw-cannot-be-used) – Ipsit Gaur Sep 28 '17 at 06:44
  • Did you notice the *copy exception detail to the clipboard* link? You should try it. It offers all the info I might need without having to look at a screenshot. All I can do now is yell at my screen *click View Detail...* – rene Sep 28 '17 at 06:49
  • already inserted the whole code in my backgroundworker – Vic Sep 28 '17 at 06:59

1 Answers1

0

As Aspirin mentioned in the comment you shouldn´t call Connection.Close on your own. But that´s not a general rule. You´re right that the connection should be closed to free unmanaged resources like a connection to the database or file-handlers. However in your case as you have an enclosing using-block that will automatically call Dipose when the variable gets out of scope and thus will call Connection.Close this latter call is done twice causing the exception when you´re closing the connection yourself.

Your using-block would be similar to this:

OleDbConnection con;
try
{
   con = new OleDbConnection(...);
    // ...
   con.Close();
}
finally
{
    if(con != null) con.Close();
}

Causing Close to be called twice on a successful run.

So you can simply omit the call to cnn.Close. because it´s allready done implicietly.

MakePeaceGreatAgain
  • 35,491
  • 6
  • 60
  • 111