COM object that has been separated from its underlying RCW can not be used.

pasensyoso_manigbas

Well-known member
Joined
May 19, 2006
Messages
64
Programming Experience
Beginner
hi mods,

i have tried to insert a query inside a Function which i invoke using a thread. the problem is when i execute the Function it prompts an error like this:

Additional information: COM object that has been separated from its underlying RCW can not be used.

my code is something like

Function myFunction(lst as listview) as String
'some codes here

for i as integer=0 to lst.Items.Count-1

dim cmd as new OledbCommand("Exec SaveRecord '" & lst.Items(x).Subitems(4).ToString & "'",connection)
cmd.ExecuteNonQuery()

Next
End Function

any help is appreciated....:)
 

jmcilhinney

VB.NET Forum Moderator
Staff member
Joined
Aug 17, 2004
Messages
14,726
Location
Sydney, Australia
Programming Experience
10+
Then what do you mean by "i invoke using a thread"? Are you using a delegate to invoke the method on the UI thread? If not, what does that mean? Also, exactly what line is the exception thrown on?
 

pasensyoso_manigbas

Well-known member
Joined
May 19, 2006
Messages
64
Programming Experience
Beginner
sorry... i have mistaken... its the other way around.. worker thread that is...
it works fine when i delegate it... but when i used a worker thread it throws an error.. the one i stated above....

the error points here

this part...

dim cmd as new OledbCommand("Exec SaveRecord '" & lst.Items(x).Subitems(4).ToString & "'",connection)
cmd.ExecuteNonQuery()
 

jmcilhinney

VB.NET Forum Moderator
Staff member
Joined
Aug 17, 2004
Messages
14,726
Location
Sydney, Australia
Programming Experience
10+
Well you just answered your own question. You aren't supposed to access control members from worker threads and this is a prime example of why. Sometimes it will work OK and others it won't. Unless you want to spend the best years of your life cataloguing which control members can be access from a worker thread under which conditions I suggest that you just do the right thing and ALWAYS use a delegate. Your function should look like this:
VB.NET:
Private Delegate Sub MySubDelegate(ByVal lst As ListView)

Private Function MyFunction(ByVal lst As ListView) As String
    'some codes here

    Me.MySub(lst)
End Function

Private Sub MySub(ByVal lst As ListView)
    If lst.InvokeRequired Then
        lst.Invoke(New MySubDelegate(AddressOf MySub), lst)
    Else
        Dim cmd As New OleDbCommand("Exec SaveRecord @Param", connection)

        cmd.Parameters.Add("@Param", OleDbType.VarChar)

        For i As Integer = 0 To lst.Items.Count - 1 Step 1
            cmd.Parameters("@Param").Value = lst.Items(i).SubItems(4).Text
            cmd.ExecuteNonQuery()
        Next
    End If
End Sub
 

pasensyoso_manigbas

Well-known member
Joined
May 19, 2006
Messages
64
Programming Experience
Beginner
i tried this code.... and it returns syntax error in "lst" saying.. "Value of type 'System.Windows.Forms.ListView' cannot be converted to '1-dimensional array of System.Object'.
"
 

jmcilhinney

VB.NET Forum Moderator
Staff member
Joined
Aug 17, 2004
Messages
14,726
Location
Sydney, Australia
Programming Experience
10+
I wrote that in VB 2005 and they've changed the signature of Control.Invoke in .NET 2.0. The second argument is now a ParamArray so you can pass loose objects. Previously it was not so you have to literally pass an Object array:
VB.NET:
lst.Invoke(New MySubDelegate(AddressOf MySub), New Object() {lst})
 

pasensyoso_manigbas

Well-known member
Joined
May 19, 2006
Messages
64
Programming Experience
Beginner
geez... sometimes hopping with .net 2005 and 2003 confuses me... Thanx
 

jmcilhinney

VB.NET Forum Moderator
Staff member
Joined
Aug 17, 2004
Messages
14,726
Location
Sydney, Australia
Programming Experience
10+
Top Bottom