Ayaz Alifov
Ayaz Alifov

Reputation: 8588

webbrowser control - releasing resources of an application

My problem is that I created a simple application where I have webrowser control. It navigates every 20 seconds to a new site. After some number of navigations memory occupied by the application increases. I tried to dispose, delete and create again the webrouser control, but couldn't succeed. The only way to release all resources of the application is reboot it. I spent lots of effort trying to solve this problem. Please, give me some hints or links where I can read about it. Thanks in advance.

The actual code is much bigger than the demonstrated one, but the idea is the same. Code looks like this:

for (int i = 0; i < 100000; i++)
{
    webBrowser1.Navigate("http://stackoverflow.com");
    Wait(20000);
}

Method definition:

private void Wait(long value)
{
    Stopwatch sw = new Stopwatch();
    sw.Start();

    while (sw.ElapsedMilliseconds < value)
        Application.DoEvents();
}

Problem is not actual now because the solution is found by using another browser control named WebKitBrowser. Thanks for all who tried to help me. It was my first question on this briliant site. I liked it very much.

Upvotes: 2

Views: 1206

Answers (3)

Ayaz Alifov
Ayaz Alifov

Reputation: 8588

I solved the problem using WebKit Browser. Here is the link for those who are also interested in using it: http://webkitdotnet.sourceforge.net/basics.php?p=4

Upvotes: 0

Ayaz Alifov
Ayaz Alifov

Reputation: 8588

The problem is still actual. I tried to use a method shown in below link but didn't succeed. How to Fix the Memory Leak in IE WebBrowser Control?

It decreases the memory for a while, then again increases significantly. And so circularly. Here is the modified code:

  public partial class Form1 : Form
   {

       [DllImport("KERNEL32.DLL", EntryPoint = "SetProcessWorkingSetSize", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
       internal static extern bool SetProcessWorkingSetSize(IntPtr pProcess, int dwMinimumWorkingSetSize, int dwMaximumWorkingSetSize);

       [DllImport("KERNEL32.DLL", EntryPoint = "GetCurrentProcess", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
       internal static extern IntPtr GetCurrentProcess();



      private void button1_Click(object sender, EventArgs e)
        {

           for (int i = 0; i < 100000; i++)
              {
                 webBrowser1.Navigate("http://stackoverflow.com");
                 while (webBrowser1.ReadyState != WebBrowserReadyState.Complete) Application.DoEvents();

                // anytime when I want to reduce the occupied memory I do this
                IntPtr pHandle = GetCurrentProcess();
                SetProcessWorkingSetSize(pHandle, -1, -1);
              }
        }



   }

Upvotes: 1

Nick Butler
Nick Butler

Reputation: 24383

You're blocking your main UI thread message loop and using Application.DoEvents, which is evil!

Instead of this, you can use a System.Windows.Forms.Timer like this:

class Form1 : Form
{
  Timer _Timer;
  int _Index = 0;

  public Form1()
  {
    _Timer = new Timer { Enabled = true, Interval = 20000 };
    _Timer.Tick += ( s, e ) => TimerTick();
  }

  void TimerTick()
  {
     if ( _Index >= 100000 )
     {
       _Timer.Dispose();
       _Timer = null;
       return;
     }

     webBrowser.Navigate( ... );

     _Index++;
   }

I'm guessing this will solve your problem. In any case, it's worth doing.

Upvotes: 0

Related Questions