none
InvokeScript raising incongruous InvalidCastException RRS feed

  • Question

  • I'm getting the following exception:
    System.InvalidCastException: Specified cast is not valid.
       at System.Windows.Forms.UnsafeNativeMethods.IHTMLDocument2.GetLocation()
       at System.Windows.Forms.WebBrowser.get_Document()
       at StarTraX.Form1.PositionCamera() in C:\Alan\VBProjects\3DTrackDisplay1\Form1.vb:line 1974

    line 1974 is :
    retObj = WebBrowser1.Document.InvokeScript("jsSLA") - as you can see, no "cast", hence the anomality. It's is in a Sub that handles a timer event, and only raises the exception on the second and all subsequent occasions.

    To debug the problem, I have stripped the code to the very basic essentials so than now jsSLA (a JS function in my WebBrowser HTML document) does absolutely nothing but return "OK".

    The code works in a much simpler sandpit development project, so I think I've encountered some sort of environmental limit, as the VS debugger fails to follow the code.

    I'm happy to implement a work-around, but after a week of fiddling, have run out of ideas.
     
    The references to UnsafeNativeMethods, HTMLDocument2, GetLocation() and get_Document() must come from "below the surface" as they're not in my code, so any help will be greatly appreciated.

    VB2005 .NET 2.0

    Saturday, October 18, 2008 9:47 PM

Answers

  • Cracked it!
    All to do with the threading model.
    I was calling the InvokeScript from a sub called directly from the timer event handler.

    When I implemented :
         Public Delegate Sub timerPointer()
    and
        Private Sub myTimerElapsed(ByVal sender As Object, ByVal e As ElapsedEventArgs) Handles myTimer.Elapsed
            Me.BeginInvoke(New timerPointer(AddressOf PrepNextFrame))
        End Sub

    It all worked OK.

    I don't claim to understand the MSDN :
    "Control.BeginInvoke Method

    Executes a delegate asynchronously on the thread that the control's underlying handle was created on."

    but I can see there is some very clever stuff happening here, and if you don't get it right it takes its bat and ball and goes home!

    Thanks for your attention - I look forward to more conversations.


    • Marked as answer by StarTraX Sunday, October 19, 2008 8:50 PM
    Sunday, October 19, 2008 8:50 PM
  • Hmya, you shouldn't use any other timer but System.Windows.Forms.Timer and its Tick event.  Clearly, your real problem was that you were indeed not waiting long enough.
    Hans Passant.
    • Marked as answer by StarTraX Sunday, January 9, 2011 9:23 PM
    Sunday, October 19, 2008 9:51 PM
    Moderator

All replies

  • The generic diagnostic is that you are accessing the Document property too soon.  It takes time for IE to load the document, it is spinning wheels in the background.  The DocumentCompleted event is important, but that is not even enough, it fires multiple times if the doc contains frames.  Start with a simple 5 second timer, started by DC to see if that's the problem.  If it is, there are better workarounds.

    I remember the ball-and-star.  How did the transparency problem work out?

    Hans Passant.
    Saturday, October 18, 2008 10:52 PM
    Moderator
  • Hi again Hans,
    First, the transparency... Never did resolve - I could never get the transparency to reliably respond. Sometimes it did, sometimes not. Mostly I could get it to work by toggling Windows screen resolution to 16 bit then back to 32 - but even then it wasn't consistent. I gues it's to do with the video driver ... just was too hard!
    Back to my current issue..
    Even with a  60 second  timer it bombs out on the second cycle, so I don't think its a timing problem - after all, it works fine on the first time which is only started long after I have already loaded the page containing the google earth plugin.

    I'll have to go and find how to access the DocumentCompleted event to see if that provides any more information.

    Saturday, October 18, 2008 11:36 PM
  • I have implemented DocumentComplete debug code and find the following results:
    The DC fires once the initial page is loaded, which is before I start the timer.
    I then start the timer and the first time the timer fires, the InvokeScript code is called successfully - but the DC event does not occur. The next time it fires, 60 seconds later, the InvokeScript raises the exception as described.
    Would you expect the DC event to fire after the InvokeScript call? In my development project, which doesn't fail, the DC doesn't fire either, when the InvokeScript is behaving itself - incidentally at a timer interval of 100 ms.
    I look forward to your views.



    Sunday, October 19, 2008 12:18 PM
  • What exactly does the script do?  What kind of trigger do you use to decide to run the script a second time?
    Hans Passant.
    • Marked as answer by StarTraX Sunday, October 19, 2008 7:04 PM
    • Unmarked as answer by StarTraX Sunday, October 19, 2008 7:04 PM
    • Unmarked as answer by StarTraX Sunday, October 19, 2008 7:04 PM
    • Unmarked as answer by StarTraX Sunday, October 19, 2008 7:04 PM
    Sunday, October 19, 2008 1:03 PM
    Moderator
  • Cracked it!
    All to do with the threading model.
    I was calling the InvokeScript from a sub called directly from the timer event handler.

    When I implemented :
         Public Delegate Sub timerPointer()
    and
        Private Sub myTimerElapsed(ByVal sender As Object, ByVal e As ElapsedEventArgs) Handles myTimer.Elapsed
            Me.BeginInvoke(New timerPointer(AddressOf PrepNextFrame))
        End Sub

    It all worked OK.

    I don't claim to understand the MSDN :
    "Control.BeginInvoke Method

    Executes a delegate asynchronously on the thread that the control's underlying handle was created on."

    but I can see there is some very clever stuff happening here, and if you don't get it right it takes its bat and ball and goes home!

    Thanks for your attention - I look forward to more conversations.


    • Marked as answer by StarTraX Sunday, October 19, 2008 8:50 PM
    Sunday, October 19, 2008 8:50 PM
  • Hmya, you shouldn't use any other timer but System.Windows.Forms.Timer and its Tick event.  Clearly, your real problem was that you were indeed not waiting long enough.
    Hans Passant.
    • Marked as answer by StarTraX Sunday, January 9, 2011 9:23 PM
    Sunday, October 19, 2008 9:51 PM
    Moderator