2009-10-16 3 views
3

Я написал приложение WPF, которое использует множество элементов управления Frame для просмотра каналов камеры. При развертывании, он выходит из строя довольно случайным образом (где-то от 2 часов до 16+ часов), и я вижу их в журнале событий, последовательно:Отслеживание исключения AccessViolationException в WPF

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.RunInternal (Window окна) в System.Windows.Application.Run (окно ) в System.Windows.Application.Run() по адресу 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 
} 

EDIT: Вот еще некоторые исходный код, я озадачен, куда ошибка (т.е. когда исключение бросают)

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

ответ

5

Если вы посмотрите на модуль сбоя внизу вашего stacktrace, вы увидите msvfw32.dll. Это не DLL, используемая WPF, поэтому я предполагаю, что она исходит из некоторого активного x на загружаемой веб-странице. Я даже больше убежден в этом из-за вашего кода, подразумевающего что-то, связанное с камерами/видео, и msvfw32 имеет дело с видео (его очень старый тоже !!). Он появляется в цикле «Диспетчер», потому что Диспетчер также обрабатывает цикл сообщений Win32, который в конечном счете используется предполагаемым activex.

Кроме того, попробуйте проверить на exception here, может быть, вы можете установить аргумент Handled = истинный

+0

@Jeremiah Да, я думаю, что виновник также находится в элементе управления ActiveX. У меня есть Dispatcher.UnhandledException в основном классе, классе matrixview и классе frametimer. Основной класс - это тот, который, кажется, поймал его, я думаю, что, возможно, забыл установить Handled = true, интересно, будет ли это работать :) Я немного смущен тем, как работает Диспетчер. Один поток обрабатывает Диспетчер для всех объектов, созданных в одном потоке? И цикл сообщений Win32 находится в том же потоке? –

+0

Диспетчер WPF обрабатывает как управляемую очередь «работы», так и обрабатывает цикл сообщений win32. Сообщения Win32 и делегаты .NET чередуются при обработке на основе приоритетов. Причина, по которой он даже обрабатывает насос сообщений Win32, предназначен для обработки вещей низкого уровня (например, перетаскивания окна WPF, получения информации о мыши из os и т. Д.), А также управления любыми компонентами Win32 (например, activex). –

+0

@Jeremiah Я ошибся, приложение DispatcherUnhandledException не поймает его; видит это событие AppDomain.CurrentDomain.UnhandledException. –

Смежные вопросы