Pber
asked on
"Attempted to read or write protected memory" using COM automation from a thread
I've created an application that uses some COM automation libraries from Symantec called from threadpools. For the most part it works like a charm. I make several calls to various other methods within the same libraries without issues. One method (in the code below) seems to throw this error randomly. I've tried my bag of tricks on it, but can't seem to figure out why it is throwing this exception. The error doesn't always happen either. It seems to happen randomly. Sometimes just the first few connections, the next time it might not error at all.
Any ideas?
Here's the error/stack trace:
System.AccessViolationExce ption was unhandled
Message="Attempted to read or write protected memory. This is often an indication that other memory is corrupt."
Source="Interop.VProAuto"
StackTrace:
at VProAuto.ProtectorAutoClas s.get_Imag eJobs()
at BESR.clsBESR.GetJobData(Ob ject Callback) in C:\Documents and Settings\pbernardin\My Documents\Visual Studio 2005\Projects\BESR\v1.0.1\ BESR\clsBE SR.vb:line 67
at System.Threading._ThreadPo olWaitCall back.WaitC allback_Co ntext(Obje ct state)
at System.Threading.Execution Context.ru nTryCode(O bject userData)
at System.Runtime.CompilerSer vices.Runt imeHelpers .ExecuteCo deWithGuar anteedClea nup(TryCod e code, CleanupCode backoutCode, Object userData)
at System.Threading.Execution Context.Ru nInternal( ExecutionC ontext executionContext, ContextCallback callback, Object state)
at System.Threading.Execution Context.Ru n(Executio nContext executionContext, ContextCallback callback, Object state)
at System.Threading._ThreadPo olWaitCall back.Perfo rmWaitCall backIntern al(_Thread PoolWaitCa llback tpWaitCallBack)
at System.Threading._ThreadPo olWaitCall back.Perfo rmWaitCall back(Objec t state)
Any ideas?
Here's the error/stack trace:
System.AccessViolationExce
Message="Attempted to read or write protected memory. This is often an indication that other memory is corrupt."
Source="Interop.VProAuto"
StackTrace:
at VProAuto.ProtectorAutoClas
at BESR.clsBESR.GetJobData(Ob
at System.Threading._ThreadPo
at System.Threading.Execution
at System.Runtime.CompilerSer
at System.Threading.Execution
at System.Threading.Execution
at System.Threading._ThreadPo
at System.Threading._ThreadPo
Public Sub GetJobData(ByVal Callback As Object)
Dim oCurrentJob As VProObj.ImageJob
Dim task As PQSCHEDULERLib.Task
Dim myJob As New STRUCT_BESRJOB
Dim AgentStatus As VProObj.AgentStatus
Dim v2iAuto As VProAuto.ProtectorAuto
Try
v2iAuto = New VProAuto.ProtectorAuto
v2iAuto.Connect(host)
Try
AgentStatus = v2iAuto.Status
myJob.AgentSTATUS = AgentStatus.Description.ToString
If v2iAuto.LastSystemBackupInterval > 1 Then
myJob.Status = False
Else
myJob.Status = True
End If
Catch ex As Exception
End Try
Try
For Each oCurrentJob In v2iAuto.ImageJobs '<-- exception throws here
Try
task = oCurrentJob.Task
myJob.Task = task.DisplayName
Catch ex As Exception
'myJob.AgentSTATUS = "Task: " & ex.Message
End Try
Try
oNetworkLocation = oCurrentJob.Location(oCurrentJob.Volumes(0))
myJob.Dest_Path = oNetworkLocation.Path
myJob.Dest_UserID = oNetworkLocation.NetworkUser
Catch ex As Exception
'myJob.AgentSTATUS = ("local: " & ex.Message)
End Try
Try
oOffsiteLocation = oCurrentJob.offsitecopylocations(0)
myJob.Offsite_Path = oOffsiteLocation.Path
myJob.OffSite_UserID = oOffsiteLocation.NetworkUser
Catch ex As Exception
'myJob.AgentSTATUS = ("Offite: " & ex.Message)
End Try
Next
Catch ex As Exception
myJob.AgentSTATUS = ("General: " & ex.Message)
End Try
Catch ex As Exception
myJob.AgentSTATUS = ex.Message
End Try
BESR_Delegate(index, myJob)
End Sub
ASKER
Do you mean to call the sub twice. Once passing it "nothing". Then call it again with my actual callback?
No, you need ensure the callback function is jitted (compiled to machine code).
This is a initialization concept. you need call only one time to this function before the callback assignement.
Then the com object call the function many times.
This is a initialization concept. you need call only one time to this function before the callback assignement.
Then the com object call the function many times.
ASKER
I call the above function from a loop. I'm looping through all items in a listview and creating a new class for each item and putting them into a threadpool. I use a delegate sub to marshall the results back to the UI thread.
So in my case, I can have several hundred instances of the class. So do I do this once before the loop from a separate instance of the class and this will cause it to compile, then loop?
I've attached the loop that does the processing:
So in my case, I can have several hundred instances of the class. So do I do this once before the loop from a separate instance of the class and this will cause it to compile, then loop?
I've attached the loop that does the processing:
Dim cBESR As clsBESR
For Each lvitem As ListViewItem In lvAgent.Items
cBESR = New clsBESR
cBESR.index = lvitem.Index
cBESR.host = lvitem.Text
cBESR.BESR_Delegate = AddressOf JobStatus_Done
Try
Interlocked.Increment(threadcount)
ThreadPool.QueueUserWorkItem(AddressOf cBESR.GetJobData)
Catch ex As Exception
MsgBox(ex.Message)
End Try
Next
You can initialize the JobStatus_Done in the shared constructor in the class owner
Class myClass
shared sub new()
JobStatus_Done(nothing)
end sub
sub JobStatus_Done
....
end sub
Class myClass
shared sub new()
JobStatus_Done(nothing)
end sub
sub JobStatus_Done
....
end sub
You can see other common problem with callback at :
http://stackoverflow.com/questions/2522402
http://stackoverflow.com/questions/2522402
ASKER
Thanks for the help. It's appreciated. I tried your suggestion and still no luck. I am using COM.Interop, so I'm not sure if that last link you provided will help.
Yeah, there are lots of people with this same error. Unfortunately no general solution.
It seems to cause the error on the first few calls, then the rest are ok. If I run the routine again, it usually doesn't error at all. The odd time all calls will error out.
Yeah, there are lots of people with this same error. Unfortunately no general solution.
It seems to cause the error on the first few calls, then the rest are ok. If I run the routine again, it usually doesn't error at all. The odd time all calls will error out.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
for that, invokey it with a null parameter : GetJobData(Nothing)
Public Sub GetJobData(ByVal Callback As Object)
if Callback is nothing then return