2009-10-16 88 views
3

我已经编写了一个WPF应用程序,该应用程序使用许多Frame控件来查看摄像头供稿。在部署时,它崩溃相当随意地(2小时随时随地16+小时),我看到这些在事件日志中,连续:追踪WPF中的AccessViolationException

System.AccessViolationException: 试图读取或写入受保护的内存 。这通常表明 其他内存已损坏。在在 系统 MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG & MSG)在 System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame 帧)在 System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame 帧) .Windows.Threading.Dispatcher.Run() 在 System.Windows.Application.RunDispatcher(对象 忽略)处 System.Windows.Application.Run System.Windows.Application.RunInternal(窗口 窗口)(窗口 window)at System.Windows.Application.Run()at S tatus_Station_client.MainClass.Main()

错误的应用程序状态站 client.exe,版本1.0.0.0,邮票 4ad0faa5,错误模块msvfw32.dll,5.1.2600.2180版本 ,戳41109753, 调试? 0,故障地址0x00002642。

有关如何跟踪此问题的任何想法?网页确实包含ActiveX控件,所以首先猜测是那里有问题。

我还没有能够在调试模式下跟踪这个。

try 
{ 
    if (Frame1 != null) 
     Frame1.Source = new Uri(uriWithResolution); 
} 
catch (AccessViolationException ex) 
{ 
    // log message 
} 

编辑:我也曾想过尝试正在吞噬从导航通话异常,但我不确定这是否是一个明智的做法另一件事这里的一些源代码,我很为难到哪里误差(即,其中该异常被抛出)

MatrixView.cs:

public partial class MatrixView : Window 
{ 
    System.Timers.Timer timer; 
    int pageNumber = 0; 
    IEnumerable<List<CameraInfo>> _cameraList; 
    GlobalSettings _globalSettings; 
    Screen _screen; 

    public MatrixView(List<CameraInfo> cameras, int pageFlipInterval, int camerasPerPage, GlobalSettings globalSettings, Screen screen) 
    { 
     InitializeComponent(); 
     _globalSettings = globalSettings; 
     _screen = screen; 
     _cameraList = Partition<CameraInfo>(cameras, camerasPerPage); 

     this.Dispatcher.UnhandledException += new DispatcherUnhandledExceptionEventHandler(Dispatcher_UnhandledException); 

     displayCameras(); 

     timer = new System.Timers.Timer(pageFlipInterval * 1000); // interval (in seconds) * 1000 ms/s 
     timer.Elapsed += new ElapsedEventHandler(timer_Elapsed); 
     timer.Enabled = true; 

     this.KeyUp += new System.Windows.Input.KeyEventHandler(MatrixView_KeyUp); 

     if (globalSettings.FullScreenOnLoad) 
     { 
      this.WindowStyle = WindowStyle.None; 
     } 
    } 

    void MatrixView_KeyUp(object sender, System.Windows.Input.KeyEventArgs e) 
    { 
     if (this.WindowStyle == WindowStyle.None) 
     { 
      if (e.Key == Key.F11 || e.Key == Key.Escape) 
      { 
       this.WindowStyle = WindowStyle.SingleBorderWindow; 

      } 
     } 
     else 
     { 
      if (e.Key == Key.F11) 
      { 
       this.WindowStyle = WindowStyle.None; 
      } 
     } 
     this.WindowState = WindowState.Maximized; 

    } 

    void timer_Elapsed(object sender, ElapsedEventArgs e) 
    { 
     this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new ThreadStart(delegate() 
     { 
      displayCameras(); 

     })); 

    } 

    void Dispatcher_UnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e) 
    { 
     EventLog.WriteEntry("Matrix Monitor", string.Format("Unhandled exception from Matrix Dispatcher\r\nMessage: {0}\r\nSource: {1}\r\nInnerException: {2}\r\nStack Trace: {3}\r\nFull String: {4}", e.Exception.Message, e.Exception.Source, e.Exception.InnerException, e.Exception.StackTrace, e.Exception.ToString())); 
     e.Handled = true; 
    } 

    private void displayCameras() 
    { 
     foreach (var child in uniformGrid1.Children) 
     { 
      FrameTimer c = child as FrameTimer; 
      if (c != null) 
      { 
       c.Dispose(); 
       c = null; 
      } 
     } 
     GC.Collect(); 
     GC.WaitForPendingFinalizers(); 

     uniformGrid1.Children.Clear(); 
     List<CameraInfo> camerasInPage = _cameraList.ElementAt(pageNumber); 
     int numCameras = camerasInPage.Count; 

     int sqrtOfCameras = (int) Math.Sqrt(numCameras); 
     double height = _screen.Bounds.Height/sqrtOfCameras; 
     double width = _screen.Bounds.Width/sqrtOfCameras; 
     foreach (CameraInfo camera in camerasInPage) 
     { 
      uniformGrid1.Children.Add(new FrameTimer(camera, _globalSettings, height, width)); 
     } 
     pageNumber++; 
     if (pageNumber >= _cameraList.Count<List<CameraInfo>>()) 
     { 
      pageNumber = 0; 
     } 



    } 
    public static IEnumerable<List<T>> Partition<T>(IList<T> source, int size) 
    { 
     int remainder = source.Count % size == 0 ? 0 : 1; 
     for (int i = 0; i < (source.Count/size) + remainder; i++)   
      yield return new List<T>(source.Skip(size * i).Take(size)); 
    } 
} 

FrameTimer.cs:

public partial class FrameTimer : UserControl, IDisposable 
{ 

    System.Timers.Timer timer; 
    string _uri; 
    string _noImageUrl; 
    bool? _successState = null; 
    GlobalSettings _globalSettings; 
    CameraInfo _camera; 
    Ping ping; 
    double _height; 
    double _width; 

    public FrameTimer(CameraInfo camera, GlobalSettings globalSettings, double height, double width) 
    { 
     InitializeComponent(); 

     _noImageUrl = AppDomain.CurrentDomain.BaseDirectory + "noImage.jpg"; 
     _globalSettings = globalSettings; 
     _camera = camera; 
     _height = height; 
     _width = width; 

     _uri = string.Format("http://{0}:{1}/LiveView.aspx?camera={2}", globalSettings.ServerIPAddress, globalSettings.ServerPort, camera.camName); 
     this.Dispatcher.UnhandledException += new DispatcherUnhandledExceptionEventHandler(Dispatcher_UnhandledException); 

     setUrl(); 

     timer = new System.Timers.Timer(_globalSettings.PingInterval * 1000); 
     timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed); 
     timer.Enabled = true; 

    } 

    void Dispatcher_UnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e) 
    { 
     EventLog.WriteEntry("Matrix Monitor", string.Format("Unhandled exception from Frame Dispatcher\r\nMessage: {0}\r\nSource: {1}\r\nInnerException: {2}\r\nStack Trace: {3}\r\nFull String: {4}", e.Exception.Message, e.Exception.Source, e.Exception.InnerException, e.Exception.StackTrace, e.Exception.ToString())); 
     e.Handled = true; 
    } 


    void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) 
    { 
     this.Dispatcher.BeginInvoke(DispatcherPriority.Send, new ThreadStart(delegate() 
      { 
       setUrl(); 
      })); 
    } 

    private void setUrl() 
    { 
     ping = new Ping(); 
     ping.PingCompleted += new PingCompletedEventHandler(ping_PingCompleted); 
     videoChecks checks = new videoChecks(); 

     string ipAddressToUse = checks.isIPInternal(_camera.camIP) ? _camera.camIP : _camera.camExtIP; 
     ping.SendAsync(ipAddressToUse, 1000, null); 
    } 

    void ping_PingCompleted(object sender, PingCompletedEventArgs e) 
    { 
     try 
     { 
      if (e.Reply.Status == IPStatus.Success) 
      { 
       if (_successState == null || _successState == false) 
       { 
        _successState = true; 
        string uriWithResolution = string.Format("{0}&res={1}x{2}&header=0", _uri, (int)_width, (int)_height); 

        if (Frame1 != null) 
         Frame1.Source = new Uri(uriWithResolution); 
       } 
      } 
      else 
      { 
       if (_successState == null || _successState == true) 
       { 
        _successState = false; 
        Image1.Source = new BitmapImage(new Uri(_noImageUrl)); 
       } 
      } 
     } 
     catch (ObjectDisposedException ex) 
     { 
      Dispose(); 
     } 
     finally 
     { 
      ((IDisposable)sender).Dispose(); 
     } 

    } 

    #region IDisposable Members 

    public void Dispose() 
    { 
     if (timer != null) 
     { 
      timer.Elapsed -= new System.Timers.ElapsedEventHandler(timer_Elapsed); 
      timer.Enabled = false; 
      timer.Dispose(); 
      timer = null; 
     } 

     Frame1.Source = null; 

     if (ping != null) 
     { 
      ping.PingCompleted -= new PingCompletedEventHandler(ping_PingCompleted); 
      ((IDisposable)ping).Dispose(); 
      ping = null; 
     } 
    } 

    #endregion 
} 
+3

我没有答案(对不起)处理的参数=,但对于你从导航调用吞咽异常,我不要的想法不认为这将起作用,因为(根据堆栈跟踪)异常不会在导航调用中出现,而是随后在调度程序循环中出现。所以程序将在异常发生之前退出try块。 – itowlson 2009-10-16 19:31:05

回答

5

如果您查看堆栈跟踪底部的错误模块,您将看到msvfw32.dll。这不是WPF使用的DLL,所以我假设它来自您正在加载的网页中的某个active-x。我更加确信,由于你的代码隐含着一些处理相机/视频和msvfw32处理视频的问题(它也很老了!!)。它出现在Dispatcher循环中,因为Dispatcher也处理Win32消息循环,最终被所谓的activex使用。

此外,尝试检查了exception here,也许你可以设置为true

+0

@Jeremiah是的,我认为罪魁祸首也在ActiveX控件中。 我有Dispatcher.UnhandledException在主类,矩阵视图类,和frametimer类。主要类是似乎赶上它,我想我可能忘记设置Handled = true在那里,想知道这是否会工作:) 我对Dispatcher如何工作有点困惑。是否有一个线程处理分派器的所有在同一个线程上创建的对象? Win32消息循环也在同一个线程上? – 2009-10-22 13:55:00

+0

WPF Dispatcher处理“work”的管理队列并处理win32消息循环。 Win32消息和.NET委托在根据优先级处理时进行交织。它甚至处理Win32消息泵的原因是处理低级别的事情(即拖动WPF窗口,从操作系统获取鼠标信息等),并驱动任何Win32组件(如ActiveX)。 – 2009-10-22 20:15:54

+0

@Jeremiah我错了,应用程序.DispatcherUnhandledException不能捕捉它;只有AppDomain.CurrentDomain.UnhandledException事件才能看到它。 – 2009-10-26 15:19:43