C# - WebBrowser控件似乎缓存了截图

时间:2010-06-12 23:03:58

标签: asp.net webbrowser-control

我在ASP.NET MVC 2应用程序中使用WebBrowser控件(不要判断,我在管理部分中只是为了让我使用它),这是代码:

public static class Screenshot
    {
        private static string _url;
        private static int _width;
        private static byte[] _bytes;

        public static byte[] Get(string url)
        {
            // This method gets a screenshot of the webpage
            // rendered at its full size (height and width)
            return Get(url, 50);
        }

        public static byte[] Get(string url, int width)
        {
            //set properties.
            _url = url;
            _width = width;
            //start screen scraper.
            var webBrowseThread = new Thread(new ThreadStart(TakeScreenshot));
            webBrowseThread.SetApartmentState(ApartmentState.STA);
            webBrowseThread.Start();
            //check every second if it got the screenshot yet.
            //i know, the thread sleep is terrible, but it's the secure section, don't judge...
            int numChecks = 20;
            for (int k = 0; k < numChecks; k++)
            {
                Thread.Sleep(1000);
                if (_bytes != null)
                {
                    return _bytes;
                }
            }
            return null;
        }

        private static void TakeScreenshot()
        {
            try
            {
                //load the webpage into a WebBrowser control.
                using (WebBrowser wb = new WebBrowser())
                {
                    wb.ScrollBarsEnabled = false;
                    wb.ScriptErrorsSuppressed = true;
                    wb.Navigate(_url);
                    while (wb.ReadyState != WebBrowserReadyState.Complete) { Application.DoEvents(); }
                    //set the size of the WebBrowser control.
                    //take Screenshot of the web pages full width.
                    wb.Width = wb.Document.Body.ScrollRectangle.Width;
                    //take Screenshot of the web pages full height.
                    wb.Height = wb.Document.Body.ScrollRectangle.Height;
                    //get a Bitmap representation of the webpage as it's rendered in the WebBrowser control.
                    var bitmap = new Bitmap(wb.Width, wb.Height);
                    wb.DrawToBitmap(bitmap, new Rectangle(0, 0, wb.Width, wb.Height));
                    //resize.
                    var height = _width * (bitmap.Height / bitmap.Width);
                    var thumbnail = bitmap.GetThumbnailImage(_width, height, null, IntPtr.Zero);
                    //convert to byte array.
                    var ms = new MemoryStream();
                    thumbnail.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
                    _bytes = ms.ToArray();
                }
            }
            catch(Exception exc)
            {//TODO: why did screenshot fail?
                string message = exc.Message;
            }
        }

这适用于我拍摄的第一个屏幕截图,但是如果我尝试拍摄不同网址的后续屏幕截图,则会保存新网址的第一个网址的屏幕截图,或者有时会保存3或4个屏幕截图url之前。我正在为每个屏幕截图创建一个新的WebBrowser实例,并使用“使用”块正确处理它,任何想法为什么它会以这种方式运行?

谢谢, 贾斯汀

1 个答案:

答案 0 :(得分:0)

您正在使用静态字段存储当前URL,因此多个请求(以及多个线程)都有机会导航到同一个URL,因为您没有同步任何访问权限。您应该使用将通过一个屏幕截图请求处理一个屏幕截图请求的同步队列,或者考虑使您的整个类非静态,以便您可以为每个请求实例化一个。

在旁注中,使用AutoResetEvent或其他信令机制来执行等待,而不是在循环中休眠。