当前位置: 首页 > 编程语言 > C#

如何在工作线程上创建和使用WebBrowser控件?Share

时间:2023-04-11 02:46:09 C#

我如何在工作线程上创建和使用WebBrowser控件?我正在创建一个使用http://pietschsoft.com/post/2008/07/C-Generate-WebPage-Thumbmail-Screenshot-Image.aspx截取网站截图的应用程序我正在尝试使该应用程序多线程化,但是我遇到了以下错误:[ActiveX控件'8856f961-340a-11d0-a96b-00c04fd705a2'无法实例化,因为当前线程不在单线程单元中。任何建议如何解决这个问题?我的代码基本上是这样的:ListlststrWebSites=newList();lststrWebSites.Add("http://stackoverflow.com");lststrWebSites.Add("http://www.cnn.com");foreach(lststrWebSites中的字符串strWebSite){System.Threading.ThreadStartobjThreadStart=delegate{BitmapbmpScreen=GenerateScreenshot(strWebSite,-1,-1);bmpScreen.Save(@"C:"+strWebSite+".png",System.Drawing.Imaging.ImageFormat.Png);};新的System.Threading.Thread(objThreadStart).Start();}从上面的URL复制GenerateScreenShot()函数实现:publicBitmapGenerateScreenshot(stringurl){//此方法获取网页的屏幕截图//以其完整大小(高度和宽度)呈现returnGenerateScreenshot(url,-1,-1);}publicBitmapGenerateScreenshot(stringurl,intwidth,intheight){//将网页加载到WebBrowser控件中WebBrowserwb=newWebBrowser();wb.ScrollBarsEnabled=false;wb.ScriptErrorsSuppressed=true;wb.Navigate(url);while(wb.ReadyState!=WebBrowserReadyState.Com完全){Application.DoEvents();}//设置WebBrowser控件的大小wb.Width=width;wb.Height=高度;if(width==-1){//网页全宽截图wb.Width=wb.Document.Body.ScrollRectangle.Width;}if(height==-1){//网页全高截图wb.Height=wb.Document.Body.ScrollRectangle.Height;}//获取在WebBrowser控件中呈现的网页的位图表示Bitmapbitmap=newBitmap(wb.Width,wb.Height);wb.DrawToBitmap(位图,新矩形(0,0,wb.Width,wb.Height));wb.Dispose();返回位图;尝试设置托管浏览器控件的线程的ApartmentState:varthread=newThread(objThreadStart);thread.SetApartmentState(ApartmentState.STA);线程。开始();与许多ActiveX控件一样,WebBrowser有严格的线程要求创建它的线程必须用Thread.SetApartmentState()进行初始化才能将其切换到STA。并且该线程必须抽出一个消息循环,即您从Application.Run()获得的消息循环。这使得与浏览器的对话变得非常棘手。这是让您入门的代码。请注意,已完成的回调在后台线程上运行。不要忘记调用Dispose()来关闭线程。使用系统;使用系统线程;使用System.ComponentModel;使用System.Windows.Forms;WebPagePump类:IDisposable{公共委托voidCompletedCallback(WebBrowserwb);私人ManualResetEventmStart;私有SyncHelpermSyncProvider;公共事件CompletedCallback完成;publicWebPagePump(){//启动线程,等待它初始化mStart=newManualResetEvent(false);线程t=新线程(startPump);t.SetApartmentState(ApartmentState.STA);t.IsBackground=true;t.开始();mStart.WaitOne();}publicvoidDispose(){//关闭消息循环和线程mSyncProvider.Terminate();}publicvoidNavigate(Uriurl){//开始导航到一个URLmSyncProvider.Navigate(url);}voidmSyncProvider_Completed(WebBrowserwb){//导航完成,引发事件CompletedCallbackhandler=Completed;如果(处理程序!=null)处理程序(wb);}privatevoidstartPump(){//开始消息循环mSyncProvider=newSyncHelper(mStar吨);mSyncProvider.Completed+=mSyncProvider_Completed;应用程序运行(mSyncProvider);}classSyncHelper:Form{WebBrowsermBrowser=newWebBrowser();ManualResetEventmStart;公共事件CompletedCallback完成;publicSyncHelper(ManualResetEventstart){mBrowser.DocumentCompleted+=mBrowser_DocumentCompleted;mStart=开始;}publicvoidNavigate(Uriurl){//开始导航this.BeginInvoke(newAction(()=>mBrowser.Navigate(url)));}voidmBrowser_DocumentCompleted(objectsender,WebBrowserDocumentCompletedEventArgse){//生成的完成事件Completed(mBrowser);}publicvoidTerminate(){//关闭表单和消息循环this.Invoke(newAction(()=>this.Close()));}protectedoverridevoidSetVisibleCore(boolvalue){if(!IsHandleCreated){//首次初始化,创建句柄并等待消息泵运行this.CreateHandle();this.BeginInvoke(newAction(()=>mStart.Set()));}//保留表单hiddenvalue=false;基础e.SetVisibleCore(值);}}}将Main方法的属性从STAThread更改为MTAThread有帮助吗?示例:[STAThread]publicstaticvoidMain(){改为:以上为C#学习教程:如何在工作线程上创建和使用WebBrowser控件?分享的所有内容,如果对你有用,需要了解更多C#学习教程,希望大家多多关注——[MTAThread]publicstaticvoidMain(){本文收集自网络,不代表一个位置。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: