Quantcast
Channel: ClearScript
Viewing all articles
Browse latest Browse all 2297

Created Unassigned: Cannot access a disposed object Error [114]

0
0
I get a weird "Cannot access a disposed object." error which I cant track down for its evil root.

Im stuck in not finding the cause and out of ideas.
its going to be difficult to explain, but basically I have 2 VBScript Engines instances running the same code in a sequential, non-parallel order. like:

```
var engine1 = new VBScriptEngine();
engine1.Execute(..);
engine1.Execute(..);
try {
engine1.Execute("engine1.Interrupt()");
} catch (Exception e) {
if (!(e is ScriptInterruptedException || e?.InnerException is ScriptInterruptedException))
throw e;
}
engine1.Dispose();
engine1 = null;

var engine2 = new VBScriptEngine();
engine2.Execute(..);
engine2.Execute(..);
try {
engine2.Execute("engine2.Interrupt()");
} catch (Exception e) {
if (!(e is ScriptInterruptedException || e?.InnerException is ScriptInterruptedException))
throw e;
}
engine2.Dispose();
engine2 = null;

```

If I dont call the Dispose() method after an engine finishes its job with a final Interrupt() call inside a loaded Script Document, everything is doing fine.

but on calling the Dispose() method on the 1st VBScript Engine after it finishes all tasks and stops with an Interrupt() call, the 2nd VBScript Engine still makes it to end of all its user script including the final Interrupt() call from within a Script document, but than somehow hits an "Cannot access a disposed object" Error after the engine successfully catches the Interrupt Exception.

I ve attached some screenshots where I think they might be better to further analyze the issue.

in addition some short descriptions to the attached images:

(se_all_intrptex.PNG)
1st script engine runs all script code, finishes and finally calls Interrupt() inside a script document, hitting the breakpoint in WindowsScriptEngine.Site.cs:231.

(se1_1oninvokeex.PNG)
hits InvokeMethod(...):177
and continues with Marshal.GetObjectForNativeVariant(...)

(se1_ondisposeex.PNG)
step-in next stops at CoTaskMemBlock.cs - Dispose():85
NOTICE the exception in the Locals Window writes: Exception HRESULT 0x80020101

(se1_errout.PNG + se1_errout_det.PNG)
last significant break seems to be here, where the exception catched before is being thrown.


when the 2nd script engine finishes all user script and receives the Interrupt() call, things go the same except that the Exception in the Locals Window (se2_2ondisposeex.PNG) now writes "Cannot access a disposed object..."

further it continues and throws a TargetInvocationException with the "Cannot access a disposed object" inside as inner exception.

the only difference I could catch here is that omitting the Dispose() call on the script engines produces all times a HRESULT 0x80020101 Exception as soon as CoTaskMemBlock.cs - Dispose():86 is hit.

but by having the Dispose() calls, all scripts engines created afterwards will produce a "Cannot access a disposed object".

one more to note: the object which is being noted as disposed is a: Microsoft.ClearScript.Windows.VBScriptEngine' object. the screenshots: se2_1oninvokeex.PNG, se2_2ondisposeex.PNG just suck in showing it.

I tried to step trough into any line inside the clearscript implementation where the scriptengine.IsDisposed prop was set to true, but no luck. I could not find any context where the scriptengine was marked as IsDisposed=true before the exception "Cannot access a disposed object" was thrown.

anyways, my quick fix so far is a simple exception check similar to:
```
...
catch (Exception e) {
if !(myFlag.IsScriptFinished && e.InnerException != null && e.InnerException.Message.Contains("Cannot access a disposed object."))
throw e;
}
...
```

much appreciate any help. thanks






Viewing all articles
Browse latest Browse all 2297