• 0

"Function Expected" IE10 Script Error on Disposing of WebBrowser ST


Question

Point of application,

Render Provided html string and print it using Internet Explorer, quickly in the background.

Problem,

WebBrowser control requires to be run in an STA thread stopping this thread (after Disposing the Web Browser) causes an IE script error.

I have a class which starts a WebBrowser Control in an STA thread,

    class RenderHtml : System.Windows.Forms.ApplicationContext
    {
// stuff
        private WebBrowser browser = null;
// more stuff
        public RenderHtml()
        {
            renderThread = new Thread(Run);
            renderThread.SetApartmentState(System.Threading.ApartmentState.STA);
            renderThread.Start();
        }

        private void Run()
        {
// Error Checking Omitted
                    browser = new WebBrowser();
                    browser.DocumentCompleted += HasRendered;
                    browser.ScriptErrorsSuppressed = true;
            Application.Run(this);

Then, I give pipe it Html to load,

        public void RenderNew(string html, AutoResetEvent resultEvent)
        {
// Error Checking Omitted
                    browser.DocumentText = html;
                    browser.Refresh();
// AutoResetEvent Logic Omitted
        }

Then after it finished rendering, I tell it to print to a specific virtual printer.

That all works.

So now, I need to dispose of it.

This is what I have right now

        protected override void Dispose(bool disposing)
        {
            lock (locko)
            {
                if (renderThread != null)
                {
                    renderThread.Abort();
                    renderThread = null;
                    return;
                }
            }
            browser.DocumentCompleted -= HasRendered;
            System.Runtime.InteropServices.Marshal.Release(browser.Handle);
            browser.Dispose();
            base.Dispose(disposing);
        }

        public void Stop()
        {
            resultEvent.Dispose();

            browser.Stop();
            ExitThread();
            Dispose();
        }

The problem is with both renderThread.Abort() and ExitThread() - I have to commit both out not to get an error.

Both of these fail due to the WebBrowser control.

I don't feel like providing a screenshot, so here is the text,

The error comes from IE itself,

Script Error
An error has occurred in the script on this page.
Line: 289
Char: 1
Error: Function Expected
Code: 0
URL: res://ieframe.dll/preview.js

Do you want to continue running scripts on this page?

So, after calling Dispose methods including the WebBrowsers dispose method.

I try to stop the thread. Which gives me this error.

If I did NOT provide any html to render I think (been a long time) there is no Script Error.

But then, it completely kills the point of the application!

Note I do suppress Script Errors - when I created the WebBrowser.

                    browser.ScriptErrorsSuppressed = true;

Also, does anyone know of a way to provide images to the WebBrowser control without going through saving them to disk?

2 answers to this question

Recommended Posts

  • 0

EDIT: Code is Available if you have no f-ing idea what I am talking about.

Now to dispose a WebBrowser,

I can do it from the STA Thread Which runs the Web Browser using Application.run(this).

So I can dispose the WebBrowser when it triggers an even such as a DocumentCompleted event.

Additionally, I can dispose of the Web Browser by using .Invoke(...) method.

Sadly WebBrowser cannot be disposed of from another thread by simply calling the Dispose() method.

I can also set the reference to the STA thread to null as well well as the reference to the WebBrowser

and set the thread to be a background thread.

The issue is, the thread does not terminate.

And to release all memory I have to terminate the damn thread.

Whether before or after dispose, whether from a separate thread or the STA Thread itself (during the DocumentCompleted event)

I get this error.

I guess I am asking is, how am I supposed to properly stop a ApplicationContext with a Web Browser Control properly and dispose of it WITHOUT any errors?

1. Why doesn't the renderThread exit itself (Abort is bad from what I understand)?

2. From where do I Abort the renderThread (STA Thread)? The calling thread (which uses the code)? renderThread itself?

3. Do I abort the thread before or after disposing of the WebBrowser?

4. Is the most proper way to dispose of a WebBrowser from another (calling) thread is to use browser.Invoke(...)?

5. Now there is Exit() ExitThread() renderThread.Abort() ExitThreadCore() - they all give me the same error... where am I supposed to call them to avoid bull?

Also this error may help,

A first chance exception of type 'System.Runtime.InteropServices.InvalidComObjectException' occurred in System.Windows.Forms.dll

Edited by _Alexander
  • 0

Workaround Solution

Even after calling browser.Dispose(),

waiting for the browser.Disposed event handler to finish,

and checking browser.IsDisposed before calling renderThread.Abort()

I still got the dreaded Script Error - An error has occurred in the script on this page Line 289 Char 1 Function Expected Code 0 URL res://ieframe.dll/preview.js

You may also get Script Error - An error has occurred in the script on this page Line 518 Char 1 Error The callee (server [not server application]) is not available and disappeared; all connections are invalid. The call did not execute. Code 0 URL res://ieframe.dll/preview.js

Create Separate Thread Which Waits 1 Second After The WebBrowser is Disposed and the calls renderThread.Abort()

Here is the code for this,

        public void TryDispose()
        {
            //
            // Do not Dispose Twice
            //

            if (_doDispose)
                return;

            _doDispose = true;

            //
            // Dispose Browser
            //

            browser.Invoke(
                new MethodInvoker
                    (
                        () =>
                        {
                            browser.Stop();

                            browser.DocumentCompleted -= HasRendered;
                            browser.Disposed += SetDisposeEvent;

                            if (browser.ActiveXInstance != null)
                                Marshal.ReleaseComObject(browser.ActiveXInstance);
                            if (browser.Handle != null)
                                Marshal.Release(browser.Handle);

                            browser.Dispose();

                        }
                    )
                );

            //
            // Hack Around - Create a Thread which Waits for 1 second before disposing the Web Browser
            //

            var browserDisposeThread = new Thread
                (
                    () =>
                    {
                        disposeEvent.WaitOne(1000);
                        Thread.Sleep(1000); // Wait to Avoid Script Error <:::::::::::::::::::::::
                        if (renderThread.IsAlive)
                        {
                            renderThread.Abort();
                            renderThread = null;
                            browser = null;

                            _applicationThreadReady.Dispose();
                            disposeEvent.Dispose();
                            if (resultEvent != null) resultEvent.Dispose();
                        }
                    }
                );
            browserDisposeThread.Name = "Browser Dispose Thread For " + renderThread.Name;
            browserDisposeThread.IsBackground = true;
            browserDisposeThread.Start();

            Console.WriteLine("TryDispose");
        }

Suggestions, Comments welcome.

Edited by _Alexander
This topic is now closed to further replies.
  • Posts

    • Well I've done a grand total of nothing, and it now clocks between 2010mhz and 1995mhz (stock is 1710mhz) and hovers around 80c, warmer than it used to, but tolerable clocks seem to have returned. Thanks for all the advice on this thread. Will review the evidence and make a choice.
    • Audacious 4.6.1 by Razvan Serea Audacious is a lightweight, open-source audio player that emphasizes simplicity, performance, and sound quality. Designed for Linux, Windows, and macOS, it supports a wide range of audio formats, internet radio streaming, and playlist management. Users can customize the interface with Winamp-style skins or modern themes, making it flexible for different preferences. Audacious also includes an equalizer, advanced audio effects, and a plugin system for extending functionality. Its low resource usage makes it especially suitable for older computers or users who value efficiency without sacrificing playback quality. Audacious key features: High audio quality – delivers clean, gapless playback with minimal distortion. Wide format support – plays MP3, FLAC, Ogg Vorbis, AAC, WAV, WMA, and more. Internet radio streaming – supports Shoutcast, Icecast, and other online streams. Winamp skin support – classic, nostalgic look for users who prefer the old-school style. Modern GTK-based interface – clean, simple UI with a more modern feel. Customizable themes – change appearance through skins and themes. Advanced playlist management – organize, save, and edit playlists with ease. Equalizer – fine-tune audio output with a built-in graphical equalizer. Audio effects – built-in DSP options like crossfade, replay gain, and more. Plugin system – extend functionality with additional components. File metadata support – displays and organizes music based on tags. Drag-and-drop support – quickly add songs or playlists. Global hotkey support – control playback without switching windows. Bit-perfect output modes – bypass system mixers for pure audio output. ReplayGain support – normalizes track loudness automatically. Cue sheet support – play entire albums from a single audio file with .cue. MPRIS2 integration – integrates with Linux desktop environments for media controls. Advanced resampling options – adjust playback quality with different resampler settings. Gapless playback – seamless transition between tracks encoded properly. Crossfade plugin – blend one song into the next smoothly. Last.fm scrobbling plugin – track listening history online. Remote control support – control Audacious via command-line or scripts. Lyrics plugin – display song lyrics if available. Alarm / timer plugin – start or stop playback at set times. SOX resampler plugin – high-quality resampling for audiophiles. Spectrum analyzer / visualization plugins – visual feedback while playing music. Headphone crossfeed effect – simulates speaker listening for headphones. Customizable buffer size – tweak latency and playback smoothness. Audacious 4.6.1 changelog: Use XDG cache dir to store temporary files (#1817) Accept embedded lyrics in more cases (#1818) Bump .so and plugin ABI versions retrospectively (#1819) Include Georgian translation (#1820) Fix build on systems using musl instead of glibc (#1823) Download: Audacious 4.6.1 | 48.2 MB (Open Source) Download: Portable Audacious 4.6.1 | 69.8 MB View: Audacious Website | Screenshot Get alerted to all of our Software updates on Twitter at @NeowinSoftware
    • I really wonder if this has to do with the built in VPN or "private DNS" of browsers that trip up legal requirements like cookie consent and Cloudflare (to avoid all the botnet attacks we get). And BTW some botnets still manage to get past Cloudflare, we are constantly having to tweak it to block malicious traffic that ultimately cause a DDoS.
  • Recent Achievements

    • Week One Done
      rolfus earned a badge
      Week One Done
    • One Month Later
      Leroy Jethro Gibbs earned a badge
      One Month Later
    • Conversation Starter
      flexorcist earned a badge
      Conversation Starter
    • One Month Later
      AndreaB earned a badge
      One Month Later
    • One Month Later
      agatameier earned a badge
      One Month Later
  • Popular Contributors

    1. 1
      +primortal
      505
    2. 2
      +Edouard
      197
    3. 3
      PsYcHoKiLLa
      142
    4. 4
      ATLien_0
      89
    5. 5
      Steven P.
      80
  • Tell a friend

    Love Neowin? Tell a friend!