2009-10-16 33 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