我有一个程序,主要功能是通过UDP侦听接收远程发送的消息,根据协议在WebBrowser中打开一个指定的URL。
目前基本的网页都是可以正常使用的,可是在打开某个三维GIS网页时,程序会发生异常并崩溃,但偶尔又可以正常的访问,此网页通过WebBrowser打开时占用内存较多,根据观察最多可能会占用600-800MB内存。
异常堆栈
1 System.AccessViolationException: 尝试读取或写入受保护的内存。这通常指示其他内存已损坏。 2 在 System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg) 3 在 System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData) 4 在 System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context) 5 在 System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context) 6 在 System.Windows.Forms.Application.Run(Form mainForm) 7 在 XTXK.DTKZ.PCController.Client.Program.Main()
UDP接收消息
1 this.thread = new Thread(() => 2 { 3 while (this.Status) 4 { 5 Thread.Sleep(1); 6 7 if (this.udp == null) break; 8 if (this.udp.Available <= 0) continue; 9 10 byte[] receiveBytes = this.udp.Receive(ref RemoteIpEndPoint); 11 12 if (Received != null) 13 Received(RemoteIpEndPoint.Address, Encoding.Default.GetString(receiveBytes)); 14 } 15 }); 16 this.thread.IsBackground = true; 17 this.thread.Start();
处理请求
1 try 2 { 3 FormBrowser currentFormBrowser = null; 4 5 //遍历已打开的窗体中是否存在该资源的显示窗体 6 //如果存在则说明这是一次重复调用 直接显示此窗体即可 7 foreach (Form form in Application.OpenForms) 8 { 9 if (form is FormBrowser) 10 { 11 FormBrowser formBrowser = form as FormBrowser; 12 13 if (formBrowser.Resource.Number.Equals(resource.Number)) 14 { 15 currentFormBrowser = formBrowser; 16 } 17 } 18 } 19 20 if (currentFormBrowser == null) 21 { 22 //如果不存在 说明这是一次新的请求 需要找到请求的显示通道中当前的窗体并结束 23 for (int i = 0; i < Application.OpenForms.Count; i++) 24 { 25 Form form = Application.OpenForms[i]; 26 if (form is FormBrowser) 27 { 28 FormBrowser formBrowser = form as FormBrowser; 29 30 if (formBrowser.Resource.ScreenChannelString.Equals(resource.ScreenChannelString)) 31 { 32 formBrowser.Close(); 33 } 34 } 35 } 36 37 currentFormBrowser = new FormBrowser(); 38 } 39 40 currentFormBrowser.Show(resource); 41 } 42 catch (Exception ex) 43 { 44 Log.Exception(ex); 45 }
打开资源
1 public FormBrowser() 2 { 3 InitializeComponent(); 4 } 5 6 7 private void FormBrowser_Load(object sender, EventArgs e) 8 { 9 this.browser.ScriptErrorsSuppressed = true; 10 } 11 12 public ResourceEntity Resource 13 { 14 get 15 { 16 return this.resource; 17 } 18 } 19 20 private void FormBrowser_FormClosing(object sender, FormClosingEventArgs e) 21 { 22 if (this.browser != null && !this.browser.IsDisposed) 23 { 24 this.browser.Dispose(); 25 } 26 } 27 28 private void browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) 29 { 30 ((WebBrowser)sender).Document.Window.Error += Window_Error; 31 } 32 33 private void Window_Error(object sender, HtmlElementErrorEventArgs e) 34 { 35 e.Handled = true; 36 } 37 38 public void Show(ResourceEntity resource) 39 { 40 try 41 { 42 this.BeginInvoke(new MethodInvoker(() => 43 { 44 45 if (this.resource != null) 46 { 47 48 this.browser.Navigate(this.resource.Path); 49 this.Show(); 50 } 51 52 })); 53 54 } 55 catch (Exception ex) 56 { 57 Log.Exception(ex); 58 } 59 }