Click here to Skip to main content
15,868,016 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
Hi I have made a WebBrowser in C#. I open several sites in it in a series like one after another.

I have a dispose button also.

That disposes the WebBrowser when I click it. Simple. My question : when I click the dispose button why the webbrowser's memory resources are not released?

It is something like this: my prog ran from 5000K over time it will get to 40000k now when I click dispose button it should release the resource that the webbrowser is taking why it don't do that?

I even called GC.collect and it was no good.
Posted
Updated 22-Jun-12 11:27am
v4
Comments
Hiren solanki 20-Jan-11 9:19am    
comment from OP:ok guys what do this line really do ?
System.Diagnostics.Process.GetCurrentProcess().MaxWorkingSet = System.Diagnostics.Process.GetCurrentProcess().MinWorkingSet;
Dave Kreskowiak 22-Jun-12 16:06pm    
It doesn't do anything real useful. Unless you like limiting the size of your application in memory and like having Windows constantly swap bits of your process to disk. That'll surely kill your apps performance.
can anyone tell me how i can add cookies in my browser in c#???
Dave Kreskowiak 22-Jun-12 16:07pm    
If you're using the WebBrowser object, cookie support is already there. ALl you did was wrap an instance of Internet Explorer in your application.

Did you cal WebBrowser.Dispose(true), or just WebBrowser.Dispose()? The first version disposes unmanaged resources as well.
 
Share this answer
 
Comments
Tassaduq009 20-Jan-11 0:14am    
only Dispose()
Calling Dispose or GC.Collect won't help if there are references holding on to the object. Because that will prevent the GC from freeing up the memory. Try and make sure that that is not the case.

[Edit]
---------
(in response to the comment)

Yeah but what I was referring to was the possibility of some references still remaining in memory. Example if you have a static member holding a reference to an object that has a member reference to this control, then the GC won't be able to claim the memory. It's the managed equivalent of a memory leak.
 
Share this answer
 
v3
Comments
Espen Harlinn 19-Jan-11 15:24pm    
Good answer
Nish Nishant 19-Jan-11 15:24pm    
Thanks Espen.
Tassaduq009 20-Jan-11 0:16am    
I have a way to strip every thing that the Browser have saved. After that i used to call web.Dispose(); i am going to try web.Dispose(true);
and 1 more thing what do this code really do
System.Diagnostics.Process.GetCurrentProcess().MaxWorkingSet = System.Diagnostics.Process.GetCurrentProcess().MinWorkingSet;
Nish Nishant 20-Jan-11 9:10am    
Yeah but what I was referring to was the possibility of some references still remaining in memory. Example if you have a static member holding a reference to an object that has a member reference to this control, then the GC won't be able to claim the memory. It's the managed equivalent of a memory leak.
There is a known memory leak in the webcontrol.
The 'Dispose' method and the 'GC' won't help you, once you instantiated a Webbrowser instance.

See this kb article from ms:
http://support.microsoft.com/kb/893629[^]
and on msdn social forum:
http://social.msdn.microsoft.com/Forums/en/ieextensiondevelopment/thread/88c21427-e765-46e8-833d-6021ef79e0c8[^]

Also, search on google for "webcontrol memoryleak". Years and years have passed and there is no fix for it for .NET. Even the "believed" workarounds in http://social.msdn.microsoft.com/Forums/en/ieextensiondevelopment/thread/88c21427-e765-46e8-833d-6021ef79e0c8[^] don't work.

Alternative is to use Geckofx or WebKit.
I like WebKit, it releases it's allocated memory after you call dispose or when you navigate to another webpage.
 
Share this answer
 
If you're looking in TaskManager to see how much memory your app is using, it's lying to you.

The amount of memory you see in Task Manager is memory that your app is using AND memory that the .NET CLR has RESERVED for your app to use.

Use PerfMon.msc and the .NET performance counters instead.
 
Share this answer
 
Comments
Espen Harlinn 19-Jan-11 15:24pm    
Good point
Hi,

For this, the webbrowser is unmanged resource call it like below:

Using(WebBrowser browser = new WebBrowser(new URI())
{
}

Read the article below, Garbage collection section:

Building High Performance WPF/E Enterprise Class Application in C# 4.5[^]

It talks on releasing memory on different instances, how to make your application more performance oriented, i say it's must to watch
 
Share this answer
 
Comments
[no name] 22-Jun-12 16:00pm    
And you suppose after a year and a half after the question has been answered, he is still looking for an answer?
TobiasVdb 27-Feb-15 7:59am    
Could be useful to other people visiting this page.
This is what i HAVE GOT SO FAR
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HtmlAgilityPack;
using System.Net;
namespace agility2
{
public class BrowserSession
{
private bool _isPost;
private HtmlDocument _htmlDoc;

///
/// System.Net.CookieCollection. Provides a collection container for instances of Cookie class
///

public CookieCollection Cookies { get; set; }

///
/// Provide a key-value-pair collection of form elements
///

public FormElementCollection FormElements { get; set; }

///
/// Makes a HTTP GET request to the given URL
///

public string Get(string url)
{
_isPost = false;
CreateWebRequestObject().Load(url);
return _htmlDoc.DocumentNode.InnerHtml;
}

///
/// Makes a HTTP POST request to the given URL
///

public string Post(string url)
{
_isPost = true;
CreateWebRequestObject().Load(url, "POST");
return _htmlDoc.DocumentNode.InnerHtml;
}

///
/// Creates the HtmlWeb object and initializes all event handlers.
///

private HtmlWeb CreateWebRequestObject()
{
HtmlWeb web = new HtmlWeb();
web.UseCookies = true;
web.PreRequest = new HtmlWeb.PreRequestHandler(OnPreRequest);
web.PostResponse = new HtmlWeb.PostResponseHandler(OnAfterResponse);
web.PreHandleDocument = new HtmlWeb.PreHandleDocumentHandler(OnPreHandleDocument);
return web;
}

///
/// Event handler for HtmlWeb.PreRequestHandler. Occurs before an HTTP request is executed.
///

protected bool OnPreRequest(HttpWebRequest request)
{
AddCookiesTo(request); // Add cookies that were saved from previous requests
if (_isPost) AddPostDataTo(request); // We only need to add post data on a POST request
return true;
}

///
/// Event handler for HtmlWeb.PostResponseHandler. Occurs after a HTTP response is received
///

protected void OnAfterResponse(HttpWebRequest request, HttpWebResponse response)
{
SaveCookiesFrom(response); // Save cookies for subsequent requests
}

///
/// Event handler for HtmlWeb.PreHandleDocumentHandler. Occurs before a HTML document is handled
///

protected void OnPreHandleDocument(HtmlDocument document)
{
SaveHtmlDocument(document);
}

///
/// Assembles the Post data and attaches to the request object
///

private void AddPostDataTo(HttpWebRequest request)
{
string payload = FormElements.AssemblePostPayload();
byte[] buff = Encoding.UTF8.GetBytes(payload.ToCharArray());
request.ContentLength = buff.Length;
request.ContentType = "application/x-www-form-urlencoded";
System.IO.Stream reqStream = request.GetRequestStream();
reqStream.Write(buff, 0, buff.Length);
}

///
/// Add cookies to the request object
///

private void AddCookiesTo(HttpWebRequest request)
{
if (Cookies != null && Cookies.Count > 0)
{
request.CookieContainer.Add(Cookies);
}
}

///
/// Saves cookies from the response object to the local CookieCollection object
///

private void SaveCookiesFrom(HttpWebResponse response)
{
if (response.Cookies.Count > 0)
{
if (Cookies == null) Cookies = new CookieCollection();
Cookies.Add(response.Cookies);
}
}

///
/// Saves the form elements collection by parsing the HTML document
///

private void SaveHtmlDocument(HtmlDocument document)
{
_htmlDoc = document;
FormElements = new FormElementCollection(_htmlDoc);
}
}
///
/// Represents a combined list and collection of Form Elements.
///

public class FormElementCollection : Dictionary<string,>
{
///
/// Constructor. Parses the HtmlDocument to get all form input elements.
///

public FormElementCollection(HtmlDocument htmlDoc)
{
var inputs = htmlDoc.DocumentNode.Descendants("input");
foreach (var element in inputs)
{
string name = element.GetAttributeValue("name", "undefined");
string value = element.GetAttributeValue("value", "");
if (!name.Equals("undefined"))
try { Add(name, value); }
catch (ArgumentException) { }
}
}

///
/// Assembles all form elements and values to POST. Also html encodes the values.
///

public string AssemblePostPayload()
{
StringBuilder sb = new StringBuilder();
foreach (var element in this)
{
string value = System.Web.HttpUtility.UrlEncode(element.Value);
sb.Append("&" + element.Key + "=" + value);
}
return sb.ToString().Substring(0);
}
}
}

Call it like this
BrowserSession b = new BrowserSession();
string response2 = b.Get("http://forum.ou1.ru/index.php?act=Login2");
/// Name of the fields
b.FormElements["UserName"] = "reneeblizzard";
b.FormElements["PassWord"] = "71c4d7e0ba4bcdf0ee8c69a5c4166110";
string response = b.Post("http://forum.ou1.ru/index.php?act=Login2");
Console.WriteLine(response);
I had success with
http://manawapt.com/forum/index.php?action=login2 success
http://manawapt.com/forum/index.php?action=profile;u=153737
fail
can any one explain why?
 
Share this answer
 
Use this code after each page load.

C#
System.Diagnostics.Process loProcess = System.Diagnostics.Process.GetCurrentProcess();
                try
                {


                        loProcess.MaxWorkingSet = (IntPtr)((int)loProcess.MaxWorkingSet - 1);
                        loProcess.MinWorkingSet = (IntPtr)((int)loProcess.MinWorkingSet - 1);
                }
                catch (System.Exception)
                {

                    loProcess.MaxWorkingSet = (IntPtr)((int)1413120);
                    loProcess.MinWorkingSet = (IntPtr)((int)204800);
                }
 
Share this answer
 
Comments
markovl 22-Jun-12 7:44am    
You do realize this is an year and half old question, right?

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900