asp.net程序里增加了这段代码后,服务器内存不断增加,直至程序池内存超限回收!我不太懂程序,查了很久也不见效,请高手指教(替换前后的全部程序代码在这里):WebBrowser m_WebBrowser = null; 
    private void _GenerateHtmlToImgImage()
    {
         m_WebBrowser = new WebBrowser();
         System.Windows.Forms.Timer t = new System.Windows.Forms.Timer();
         t.Enabled = false;
         t.Interval = 10000;
         t.Tick += t_Tick;
           m_WebBrowser.ScrollBarsEnabled = false;
         t.Enabled = true;
         m_WebBrowser.Navigate(m_Url);
         m_WebBrowser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(WebBrowser_DocumentCompleted);
                   while (m_WebBrowser != null && m_WebBrowser.ReadyState != WebBrowserReadyState.Complete)
             Application.DoEvents();
         if (m_WebBrowser != null)
             m_WebBrowser.Dispose();
                 m_WebBrowser = null;
     }
       void t_Tick(object sender, EventArgs e)
     {
         ((System.Windows.Forms.Timer)sender).Stop();
           WebBrowser tmp = m_WebBrowser;
         if (tmp != null)
         {
             m_WebBrowser = null;
             if (tmp.ReadyState != WebBrowserReadyState.Complete)
             {
                 tmp.Stop();
                 tmp.Dispose();
             }
         }

解决方案 »

  1.   

    webbrowser相当于嵌入一个ie啦,本身如果javascript如果编写的不是很完善的话,ie会有内存泄露的。这个几乎无解。除非你能针对特定的问题做hack,相当于对造成内存泄露的脚本做patch。对于ie来说,不正确地循环引用变量,闭包变量被扩大了变量的生命周期等等很多情况下都会造成泄露。
      

  2.   

    觉得自己一个门外汉,胡乱排查内存问题到凌晨很辛苦。没想到版主比我还辛苦
    这个代码之前没有内存泄露,就是增加了这个时间限制之后才出现的内存问题,所以我才下大力寻找的!能否拜托版主帮我仔细看看?这是修改前的代码,只修改了这部分,其余没动(修改前的全部程序代码在这里):    private void _GenerateHtmlToImgImage()
        {
            WebBrowser m_WebBrowser = new WebBrowser();
            m_WebBrowser.ScrollBarsEnabled = false;
            m_WebBrowser.Navigate(m_Url);
            m_WebBrowser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(WebBrowser_DocumentCompleted);
            while (m_WebBrowser.ReadyState != WebBrowserReadyState.Complete)
                Application.DoEvents();
            m_WebBrowser.Dispose();
        }
      

  3.   

    版主你好!之前没有内存泄露,我只修改了一小段代码就出问题了。恳请版主帮我看看代码!楼上是早前没有内存泄露的代码,下面是修改后有泄漏的代码(增加了10秒内结束程序的语句):WebBrowser m_WebBrowser = null; 
        private void _GenerateHtmlToImgImage()
        {
             m_WebBrowser = new WebBrowser();
             System.Windows.Forms.Timer t = new System.Windows.Forms.Timer();
             t.Enabled = false;
             t.Interval = 10000;
             t.Tick += t_Tick;
               m_WebBrowser.ScrollBarsEnabled = false;
             t.Enabled = true;
             m_WebBrowser.Navigate(m_Url);
             m_WebBrowser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(WebBrowser_DocumentCompleted);
                       while (m_WebBrowser != null && m_WebBrowser.ReadyState != WebBrowserReadyState.Complete)
                 Application.DoEvents();
             if (m_WebBrowser != null)
                 m_WebBrowser.Dispose();
                     m_WebBrowser = null;
         }
           void t_Tick(object sender, EventArgs e)
         {
             ((System.Windows.Forms.Timer)sender).Stop();
               WebBrowser tmp = m_WebBrowser;
             if (tmp != null)
             {
                 m_WebBrowser = null;
                 if (tmp.ReadyState != WebBrowserReadyState.Complete)
                 {
                     tmp.Stop();
                     tmp.Dispose();
                 }
             }
      

  4.   

    你这个_GenerateHtmlToImgImage函数是不是频繁调用,或者就是在定时器时间周期内调用?看起来是要实现超时,有点晕乎。
    不过这段代码看着不舒服:
    WebBrowser tmp = m_WebBrowser;
             if (tmp != null)
             {
                 m_WebBrowser = null;
                 if (tmp.ReadyState != WebBrowserReadyState.Complete)
                 {
                     tmp.Stop();
                     tmp.Dispose();
                 }
             }
    改一下:         if (m_WebBrowser != null)
             {
                 if (m_WebBrowser.ReadyState != WebBrowserReadyState.Complete)
                 {
                     m_WebBrowser.Stop();
                 }
                 m_WebBrowser.Dispose();
                 m_WebBrowser = null;
             }
      

  5.   

    你把释放的代码放到DocumentCompleted事件和定时器事件就可以了,不用在那个函数里去死循环;另外变量我看你也没别的用处,完了要删除,应该改成局部变量,作为参数传递给定时器就行了。对了,定时器用System.Threading.Timer。
      

  6.   

    超过10秒就结束程序释放资源,这也是在论坛里得到的代码,之前没发现过内存泄露(修改前的全部程序代码在这里)。照着你的新代码改了,测试了一小时,貌似没效果,一小时吃进去一百多兆内存!
    另外,你说的全局变量是哪个?t?还是别的什么?
    还有,System.Windows.Forms.Timer t = new System.Windows.Forms.Timer();
    改成System.Threading.Timer t = new System.Threading.Timer();不知对不对,改了之后页面卡死,就又改回来了。
    基础很差,望高手不吝赐教。
      

  7.   

    今天抽空又看了下,我说的那个控件也是用webbroswer实现的。效率差不多。
    又在codeplex,上看了一个。效果也差不多,你试试看,如果这效率好些就用这个吧。
    http://webshooter.codeplex.com/
      

  8.   

    asp.net里边使用 System.Windows.Forms.Timer,这个是不想玩儿asp.net啦。web服务器主要是给很多匿名用户并发访问网页的,它的设计都是与桌面窗体或者业务服务器不同的。有些软件开发不是asp.net程序员所应该想的。就好像是在大厦门口巡逻的保安不应该以为自己的派出所民警、更不应该以为自己是刑警一样。
      

  9.   

    请不要使用System.Windows.Forms.Timer,那个在asp.net下面是不会工作的。
    下面引用MSDN原话:
    因此你后面的while循环很可能会导致了无限循环,资源不释放。正确的做法是使用System.Threading.Timer 类。
      

  10.   

    根本没有避免,t_Tick永远无法执行。
      

  11.   

    已经运行了好多天了,你可以去主贴那个链接里去看,有全部代码,你在自己机器上试试。
    System.Windows.Forms.Timer t = new System.Windows.Forms.Timer();目前在用,改成System.Threading.Timer t = new System.Threading.Timer();反倒不能用了,是不是要在页面最顶端加上这一行才可以:System.Threading.Timer
      

  12.   

    难道说WebBrowser也算是提供了可用的 UI 消息泵?System.Threading.Timer 是轻量级的定时器,微软所有带超时的方法,都是用的System.Threading.Timer在后台计时的,可见System.Threading.Timer 才是最佳的。而你说的情况是在定时器内执行了WebBrowser的操作导致的,那部分需要回调(WebBrowser.BeginInvoke)。
    而事实上,使用了定时器以后,你的那个while部分语句就可以不需要了,这也是sp1234所说的情况,你那段sp1234后面的代码完全是画社添足,应该全部放在定时器中处理。那个定时器内部就做过判断,是超时还是正常结束了,后续逻辑直接跟在后面即可。
      

  13.   

    在页面顶部加了using System.Threading.Timer之后,用System.Threading.Timer t = new System.Threading.Timer();替换System.Windows.Forms.Timer t = new System.Windows.Forms.Timer();还是不行!
    我的所有代码都在,可以帮我改改吗?现成的代码我也看不大懂,只要在此基础上能及时释放资源就行。
    先谢谢了!
      

  14.   

    我就给你简单改下,大改的话太费时间了,比如你的System.Threading.Timer,能用就别改了。
    一、while循环里原先只有Application.DoEvents();,现添加Thread.Sleep(300);让每次循环休息下。
    while(...)
    {
        Thread.Sleep(300);
        Application.DoEvents();
    }二:    private void WebBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            WebBrowser m_WebBrowser = (WebBrowser)sender;
            m_WebBrowser.ClientSize = new Size(this.m_BrowserWidth, this.m_BrowserHeight);
            m_WebBrowser.ScrollBarsEnabled = false;
            m_Bitmap = new Bitmap(m_WebBrowser.Bounds.Width, m_WebBrowser.Bounds.Height);
            m_WebBrowser.BringToFront();
            m_WebBrowser.DrawToBitmap(m_Bitmap, m_WebBrowser.Bounds);
            m_Bitmap = (Bitmap)m_Bitmap.GetThumbnailImage(m_ThumbnailWidth, m_ThumbnailHeight, null, IntPtr.Zero);
        }
    改为:    private void WebBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            WebBrowser m_WebBrowser = (WebBrowser)sender;
            m_WebBrowser.ClientSize = new Size(this.m_BrowserWidth, this.m_BrowserHeight);
            m_WebBrowser.ScrollBarsEnabled = false;
            var tmp = new Bitmap(m_WebBrowser.Bounds.Width, m_WebBrowser.Bounds.Height);
            m_WebBrowser.BringToFront();
            m_WebBrowser.DrawToBitmap(tmp , m_WebBrowser.Bounds);
            m_Bitmap = (Bitmap)tmp.GetThumbnailImage(m_ThumbnailWidth, m_ThumbnailHeight, null, IntPtr.Zero);
            tmp.Dispose();//释放临时图片资源
            tmp = null;
        }三:    protected void Button1_Click(object sender, EventArgs e)
        {
            Bitmap bmp = HtmlToImg.GetHtmlToImg("http://www.baidu.com/", 800, 600, 800, 600);
            MemoryStream stream = new MemoryStream();
            bmp.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
            byte[] buff = stream.ToArray();
      
            FileStream fs = new FileStream(Server.MapPath(DateTime.Now.ToString("yyyyMMddHHmmss") + ".jpg"), FileMode.Create);
            stream.WriteTo(fs);
            stream.Close();
            fs.Close();
        }
    改为:    protected void Button1_Click(object sender, EventArgs e)
        {
            using(Bitmap bmp = HtmlToImg.GetHtmlToImg("http://www.baidu.com/", 800, 600, 800, 600))
            {
                bmp.Save(Server.MapPath(DateTime.Now.ToString("yyyyMMddHHmmss") + ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
            }
        }此二处的Bitmap必须释放,否则就会内存泄漏。最后那个错误提示的返回方法请自选搜索,本人不搞asp.net好久了,具体代码已经忘记。
      

  15.   

    ????
    这是啥子啊asp.net 配WebBrowser,在配Timer??这代码比较奇葩想做爬虫玩快照,也不应该在asp.net里玩,你可以写成winfrom服务
      

  16.   

    谢谢!
    我不大会调试,每个步骤结果如下:
    一、增加Thread.Sleep(300);后,程序运行缓慢,长时间等待后出现正在中止线程的错误提示:“异常详细信息: System.Threading.ThreadAbortException: 正在中止线程。”
    二、编译器错误信息: CS0246: 找不到类型或命名空间名称“var”(是否缺少 using 指令或程序集引用?)
    var tmp = new Bitmap(m_WebBrowser.Bounds.Width, m_WebBrowser.Bounds.Height);
    去掉var也出错。
    三、在".jpg"后面加括号后通过了。
    这个程序原来没有内存泄露(至少我没发现),就是增加了限制时间的条件(整个程序只改了这个方法 _GenerateHtmlToImgImage)之后才有了内存泄露。能否请高手直接看看这两段更改前后的代码找出泄漏原因?
    _GenerateHtmlToImgImage方法更改前(没发现整个程序有内存泄漏):    private void _GenerateHtmlToImgImage()
        {
            WebBrowser m_WebBrowser = new WebBrowser();
            m_WebBrowser.ScrollBarsEnabled = false;
            m_WebBrowser.Navigate(m_Url);
            m_WebBrowser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(WebBrowser_DocumentCompleted);
            while (m_WebBrowser.ReadyState != WebBrowserReadyState.Complete)
                Application.DoEvents();
            m_WebBrowser.Dispose();
        }_GenerateHtmlToImgImage方法更改,限制程序时间后(内存泄漏很严重):WebBrowser m_WebBrowser = null;
        private void _GenerateHtmlToImgImage()
        {
            m_WebBrowser = new WebBrowser();
            System.Windows.Forms.Timer t = new System.Windows.Forms.Timer();
            t.Enabled = false;
            t.Interval = 10000;
            t.Tick += t_Tick;
     
            m_WebBrowser.ScrollBarsEnabled = false;
            t.Enabled = true;
            m_WebBrowser.Navigate(m_Url);
            m_WebBrowser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(WebBrowser_DocumentCompleted);
             
            while (m_WebBrowser != null && m_WebBrowser.ReadyState != WebBrowserReadyState.Complete)
                Application.DoEvents();
            if (m_WebBrowser != null)
                m_WebBrowser.Dispose();        
            m_WebBrowser = null;
        }
     
        void t_Tick(object sender, EventArgs e)
        {
            ((System.Windows.Forms.Timer)sender).Stop();
     
            WebBrowser tmp = m_WebBrowser;
            if (tmp != null)
            {
                m_WebBrowser = null;
                if (tmp.ReadyState != WebBrowserReadyState.Complete)
                {
                    tmp.Stop();
                    tmp.Dispose();                
                }
            }        
        }我的程序是七拼八凑起来的,肯定存在很多问题!但是目前最紧要的还是修改了_GenerateHtmlToImgImage方法之后造成的内存泄露。恳请高手查看具体是哪条代码出的问题!
      

  17.   

    var是.NET3.5的关键字,意思是数据类型由后面返回的类型来决定,如果你是.NET2.0,那么只能用Bitmap代替。
    按理说,所有操作是在多线程中执行的,那么该线程如果执行结束,肯定是会释放资源的,但由于你的代码是asp.net,不方便调试,你可以将代码执行逻辑(按钮点击)放在WinForm下面测试,而最后写文件部分用固定文件名替代测试,主要测试线程是否能够正常结束。另外Thread.Sleep(300);后不会导致变慢的,这个间隔几乎是感觉不到的,而System.Threading.ThreadAbortException异常是必须手动调用Thread类的Abort方法才会产生,但是你的代码中没看到这部分。
    如果实在调试不出原因,就别用System.Windows.Forms.Timer了,这里的超时很容易处理,先改用原来的代码,然后在public Bitmap GenerateHtmlToImgImage()函数中,找到“m_thread.Join();”改为:
    bool success = m_thread.Join(15000);//考虑到处理图片也要时间,增加5秒
    if(success)
        return m_Bitmap;
    else
        throw new Exception("操作超时");//这里返回的异常,由外部调用者捕获并做其它处理。
      

  18.   

    再补一句,把那个新开的线程中止了。bool success = m_thread.Join(15000);//考虑到处理图片也要时间,增加5秒
    if(success)
        return m_Bitmap;
    else
    {
        m_thread.Abort();//終止线程
        throw new Exception("操作超时");//这里返回的异常,由外部调用者捕获并做其它处理。
    }
      

  19.   

    我不懂代码也不会调试,越弄越乱了
    我把简化后的原始代码再次贴出来(就是主贴那个链接里的),这个程序除了不能超时终止之外,别的没发现异常,后来加了时间代码(主贴那个链接里提问得到的答案)就发现内存泄露了。可不可以请高手直接给我这个代码加上限制时间的代码(比如10秒,超时则终止程序释放资源)。总共3个文件:
    Default.aspx<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
      
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
            <asp:Button ID="Button1" runat="server" Text="保存网页快照" onclick="Button1_Click" />
        </div>
        </form>
    </body>
    </html>Default.aspx.csusing System;
    using System.Collections.Generic;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Drawing;
    using System.IO;
      
      
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
      
        }
        protected void Button1_Click(object sender, EventArgs e)
        {
            Bitmap bmp = HtmlToImg.GetHtmlToImg("http://www.baidu.com/", 800, 600, 800, 600);
            MemoryStream stream = new MemoryStream();
            bmp.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
            byte[] buff = stream.ToArray();
      
            FileStream fs = new FileStream(Server.MapPath(DateTime.Now.ToString("yyyyMMddHHmmss") + ".jpg"), FileMode.Create);
            stream.WriteTo(fs);
            stream.Close();
            fs.Close();
        }
    }HtmlToImage.csusing System;
    using System.Drawing;
    using System.Threading;
    using System.Windows.Forms;
      
    public class HtmlToImg
    {
        Bitmap m_Bitmap;
        string m_Url;
        int m_BrowserWidth, m_BrowserHeight, m_ThumbnailWidth, m_ThumbnailHeight;
      
        public HtmlToImg(string Url, int BrowserWidth, int BrowserHeight, int ThumbnailWidth, int ThumbnailHeight)
        {
            m_Url = Url;
            m_BrowserHeight = BrowserHeight;
            m_BrowserWidth = BrowserWidth;
            m_ThumbnailWidth = ThumbnailWidth;
            m_ThumbnailHeight = ThumbnailHeight;
        }
      
        public static Bitmap GetHtmlToImg(string Url, int BrowserWidth, int BrowserHeight, int ThumbnailWidth, int ThumbnailHeight)
        {
            HtmlToImg thumbnailGenerator = new HtmlToImg(Url, BrowserWidth, BrowserHeight, ThumbnailWidth, ThumbnailHeight);
            return thumbnailGenerator.GenerateHtmlToImgImage();
        }
      
        public Bitmap GenerateHtmlToImgImage()
        {
            Thread m_thread = new Thread(new ThreadStart(_GenerateHtmlToImgImage));
            m_thread.SetApartmentState(ApartmentState.STA);
            m_thread.Start();
            m_thread.Join();
            return m_Bitmap;
        }
      
        private void _GenerateHtmlToImgImage()
        {
            WebBrowser m_WebBrowser = new WebBrowser();
            m_WebBrowser.ScrollBarsEnabled = false;
            m_WebBrowser.Navigate(m_Url);
            m_WebBrowser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(WebBrowser_DocumentCompleted);
            while (m_WebBrowser.ReadyState != WebBrowserReadyState.Complete)
                Application.DoEvents();
            m_WebBrowser.Dispose();
        }
      
        private void WebBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            WebBrowser m_WebBrowser = (WebBrowser)sender;
            m_WebBrowser.ClientSize = new Size(this.m_BrowserWidth, this.m_BrowserHeight);
            m_WebBrowser.ScrollBarsEnabled = false;
            m_Bitmap = new Bitmap(m_WebBrowser.Bounds.Width, m_WebBrowser.Bounds.Height);
            m_WebBrowser.BringToFront();
            m_WebBrowser.DrawToBitmap(m_Bitmap, m_WebBrowser.Bounds);
            m_Bitmap = (Bitmap)m_Bitmap.GetThumbnailImage(m_ThumbnailWidth, m_ThumbnailHeight, null, IntPtr.Zero);
        } 
    }net2.0的运行环境。拜托高手直接帮我在这个完整的程序里增加限制程序运行时间的代码,超时就终止程序释放资源。
      

  20.   

        public Bitmap GenerateHtmlToImgImage()
        {
            Thread m_thread = new Thread(new ThreadStart(_GenerateHtmlToImgImage));
            m_thread.SetApartmentState(ApartmentState.STA);
            m_thread.Start();
            bool success = m_thread.Join(15000);//考虑到处理图片也要时间,增加5秒
            if(success)
                return m_Bitmap;
            else
            {
                m_thread.Abort();//終止线程
                throw new Exception("操作超时");//这里返回的异常,由外部调用者捕获并做其它处理。
            }
            return m_Bitmap;
        }
    调用:
        protected void Button1_Click(object sender, EventArgs e)
        {
            try
            {
                using(Bitmap bmp = HtmlToImg.GetHtmlToImg("http://www.baidu.com/", 800, 600, 800, 600))
                {
                    bmp.Save(Server.MapPath(DateTime.Now.ToString("yyyyMMddHHmmss") + ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
                }
            }
            catch(Exception ex)
            {
                HttpResponse response = HttpContext.Current.Response;
                response.Write(ex.Message);
                response.Close();
            }
        }
    备注,最后3行代码未测试,凭感觉写的。
      

  21.   

    你在本地测试过吗?为什么我测试的时候只要一超时就出现“Internet Explorer 无法显示该网页”啊
      

  22.   

    我的原意是通过HttpContext.Current.Response获取当前http响应,然后直接将错误信息写入,之后直接关闭响应,把默认的按钮返回信息给屏蔽。因为ASP.NET是我最初学C#的时候写过,都5年以上了,而且那个时候的基础也不好,因此如何更好的返回客户端信息这部分我只能随便写写,你可以向他人求助,比如到asp.net的专区问问,只要在那个catch部分的代码改掉即可,相信你应该可以看得懂那代码的意思。
      

  23.   

    或者对于超时处理不处理,再或者catch部分就记录错误信息到服务器端的文件内,你先测试内存泄漏是否解决
      

  24.   

    前段时间也研究过,也找到了处理的方法,只是当页面太大时,无法获取截图(全白),小型的页面还是可以的    public class GHtmlToImage
        {
            /// <summary>
            /// 地址
            /// </summary>
            private string _url = "about:blank";
            /// <summary>
            /// 宽
            /// </summary>
            private int _width = 800;
            /// <summary>
            /// 高
            /// </summary>
            private int _height = 600;
            /// <summary>
            /// 缩略图宽
            /// </summary>
            private int _swidth = 320;
            /// <summary>
            /// 缩略图高
            /// </summary>
            private int _sheight = 250;        private Bitmap _image;
            private Bitmap _thumbnailimage;
            private object _lock = new object();
            private object _lock2 = new object();
            public string Url
            {
                set { _url = value; }
            }
            public int Width
            {
                set { _width = value; }
            }
            public int Height
            {
                set { _height = value; }
            }
            public int SWidth
            {
                set { _swidth = value; }
            }
            public int SHeight
            {
                set { _sheight = value; }
            }
            public Bitmap Image
            {
                get { return _image; }
            }
            public Bitmap ThumbnailImage
            {
                get { return _thumbnailimage; }
            }
            public string DocText
            {
                get;
                set;
            }
            public int runtime
            {
                get;
                set;
            }
            public GHtmlToImage()
            {
                Thread.CurrentThread.CurrentUICulture =  Thread.CurrentThread.CurrentCulture;
            }
            /*
            [STAThreadAttribute]
            static void Main()
            {
                
            }
             */ 
            public void Init()
            {
                
                lock (_lock)
                {
                    
                    Thread _thread = new Thread(new ThreadStart(_GenerateHtmlToImgImage));
                    _thread.Name = "Galsun.Fcx.htmlToImage";
                    _thread.SetApartmentState(ApartmentState.STA);
                    _thread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;
                    _thread.Start();
                    _thread.Priority = ThreadPriority.Highest;
                    TimeSpan ts = new TimeSpan(0, 0, 0, 30);
                    _thread.Join();
                   
                    GC.Collect();
                    GC.Collect();
                }
            }
            [STAThread]
            private void _GenerateHtmlToImgImage()
            {
                
                Monitor.Enter(this);
                try
                {
                    #region 普通
                    WebBrowser _WebBrowser = new WebBrowser();
                    _WebBrowser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(WebBrowser_DocumentCompleted);
                    //_WebBrowser.ProgressChanged += new WebBrowserProgressChangedEventHandler(WebBrowser_ProgressChanged);
                    _WebBrowser.ScrollBarsEnabled = false;
                    _WebBrowser.Navigate(_url);
                    System.Windows.Forms.Timer _tm = new System.Windows.Forms.Timer();
                    _tm.Interval=1000;
                    _tm.Tick += new EventHandler(Time_Tick);
                    _tm.Enabled = true;
                    //Application.SetCompatibleTextRenderingDefault(false);
                    Application.Run();
                    //Application.EnableVisualStyles();
                    
                    
                    _WebBrowser.Dispose();
                    
                    #endregion                #region 新模式
                    /*
                    Application.EnableVisualStyles();
                    Application.SetCompatibleTextRenderingDefault(false);
                    MainForm _form = new MainForm();
                    _form._url = _url;
                    _form._width = _width;
                    _form._height = _height;
                    _form._swidth = _swidth;
                    _form._sheight = _sheight;
                    _form.Width = _width;
                    _form.Height = _height;
                    Application.Run(_form);
                    _image = _form._image;
                    _thumbnailimage = _form._thumbnailimage;
                     */ 
                    #endregion
                }
                finally
                {
                    Monitor.Exit(this);            }
            }
            private void Time_Tick(object sender, EventArgs e)
            {
                if (runtime > 0)
                {
                    Thread.Sleep(100);
                    Application.ExitThread();
                }
            }
            private void WebBrowser_ProgressChanged(object sender, WebBrowserProgressChangedEventArgs e)
            {
                WebBrowser _webBrowser = (WebBrowser)sender;
                if (e.CurrentProgress == e.MaximumProgress && _webBrowser.ReadyState == WebBrowserReadyState.Complete)
                {
                    Application.ExitThread();
                }
            }
            private void WebBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
            {
                Monitor.Enter(this);
                try
                {
                    
                    WebBrowser _webBrowser = (WebBrowser)sender;
                    if (_webBrowser.ReadyState == WebBrowserReadyState.Complete)
                    {
                        
                        
                        DocText = _webBrowser.DocumentText;
                        if(_webBrowser.Document.Body.ScrollRectangle.Height> _height)
                        {
                            _height=_webBrowser.Document.Body.ScrollRectangle.Height;
                        }
                        _webBrowser.ClientSize = new Size(_width, _height);
                        //_webBrowser.ScrollBarsEnabled = false;
                        //Application.DoEvents();
                        _image = new Bitmap(_webBrowser.Bounds.Width, _webBrowser.Bounds.Height);
                        _webBrowser.BringToFront();
                        _webBrowser.DrawToBitmap(_image, _webBrowser.Bounds);
                        _thumbnailimage = (Bitmap)_image.GetThumbnailImage(_swidth, _sheight, null, IntPtr.Zero);
                        runtime++;
                    }
                    
                }
                finally
                {
                    Monitor.Exit(this);
                }
            }
             
        }
      

  25.   

    我这里用的是Application.Run(); 和Application.Run(); 来控制,没有超时的问题,其它那些无法获取截图的页面我也不懂是什么原因,通过DocText确实是已经成功加载了的,本人认为是iis的内存分配问题
      

  26.   

    你搞错了,不是5年没写代码,而是没写asp.net,我最初接触了一段时间asp.net后,就一直从事WinForm和后台服务的编写,因此C#语言本身的使用是非常精通的。而现在则是考虑界面用WPF来实现,即使再回头看asp.net,也需要考虑转向MVC。
    另外你其它帖子发的不是.NET专区,我就不去搀和了。