2012-02-11 57 views
11

背景: 我有一个基于.Net 3.5的WPF“棱镜”的应用程序运行在Windows XP和Windows PosReady 2009个人电脑上。该应用运行在每天晚上关闭的PC上(通过C#调用“shutdown.exe”)并在早上启动(通过LAN唤醒)。该应用程序是基于触摸的(使用ELO触摸屏),没有连接鼠标或键盘,用户无法访问Windows。WPF应用程序错误和.Net框架修复

问题: 我们偶尔看到两件事中的一件发生的问题;无论是应用程序似乎没有正确加载,我们看到一个空白的白色表单显示,或者它停止响应触摸。从查看我们的(log4net)日志,我们可以看到,我们仍然在处理触摸事件,并在两种情况下将它们注销。通常这在切换视图时会发生,我们也会在日志中看到Prism RegionManager正在移除和正确添加视图。

故障排除: 该应用程序正在运行使用具有施加的Clonezilla图像〜约100的PC和发生这种情况只是偶尔。由于它没有在所有PC上发生,并且在事件查看器中没有记录异常或任何指示问题的事件,因此我们采用了更多的PC和OS级修补程序。具体而言,我们尝试重新启动应用程序和偶尔短期成功的PC - 这意味着应用程序有时会在重新启动后正常运行,但最多只需要几个小时。我们也在假设应用程序已被破坏,并且已经删除并重新安装它,但没有成功。

似乎解决此问题的唯一方法是使用提供的.Net 3.5 SP1安装程序包修复.Net框架。

结论: 由于这似乎是解决这个问题的时候没有别的呢,我们似乎在某种程度上破坏一个GAC'd框架DLL - 无论是通过代码或PC上的开机/关机程序。

问题: 这导致了一些问题:

  • 对我们如何才能进一步确定问题的根源任何想法?
  • 有关我们可以采取哪些措施来防止此问题的任何想法?
  • 有关潜在问题可能的任何想法?

感谢您的帮助。

+0

很难说..你有多线程正在进行吗?从GUI线程以外触发的任何事件? – stmax 2012-02-14 22:40:15

+0

在任何时候都有不同的线程。大多数情况下,它们都是作为BackgroundWorker对象创建的,但其中一些是使用ThreadStart显式创建的Thread对象。工作人员的寿命通常很短(创建,运行一次,销毁),并且线程通常很长时间(从应用程序的整个生命周期开始)。 Prism聚合事件在GUI线程中引发。 – 2012-02-15 22:01:00

+0

这些机器是否有任何形式的固态驱动器硬件,或者它们是否都使用廉价的硬盘驱动器运行?哎哟。 – 2012-02-18 09:06:37

回答

2

我们终于能够抓住一台展示此行为的生产机器,并通过一系列故障排除步骤,包括将转储文件发送给Microsoft,该问题就位于此处。

WPF字体缓存Windows服务偶尔会进入损坏状态,导致简单的缓存请求无限期阻止。这个挂起导致了我们WPF应用程序中上述的所有行为。

简单的解决方案:停止并禁用服务。禁用服务并重新启动PC后,服务不再使用,我们看不到任何这些问题。理论上这会导致更长的应用程序加载时间,但我们已经看到了零负面影响。

请注意,该服务有两个版本:3.0.0.0和4.0.0.0。如果您的应用程序的目标是.Net 3.0或3.5,则需要禁用3服务,如果目标为4.0以上,则需要禁用4服务。

感谢大家的意见和建议。

0

当连接触摸屏时,我们遇到了使用我们的WPF应用程序提醒您的问题。这是由于.Net自动化框架中的一个错误造成的。它导致我们的应用程序变得非常慢或完全挂起GUI线程。

您可以阅读更多关于这个问题:http://social.msdn.microsoft.com/Forums/en-IE/windowsaccessibilityandautomation/thread/6c4465e2-207c-4277-a67f-e0f55eff0110

解决方法建议在上述其中一个删除定期为我们工作的自动化事件的任何监听器线程。

这不是一个真正的答案,但因为我没有足够的代表?(我猜)我不能使用评论功能:)

+0

感谢您的评论,尽管我不认为这适用于此。我们并非起诉自动化或看到任何性能问题,并且在重新启动后无法长期恢复。 – 2012-03-09 15:53:37

0

尝试全局错误捕获,看看它产生了什么。

public partial class App : Application 
    { 
     [STAThread] 
     public static void Main() 
     { 
       var application = new App(); 

       application.DispatcherUnhandledException += 
        new DispatcherUnhandledExceptionEventHandler(application_DispatcherUnhandledException); 

       application.InitializeComponent(); 
       application.Run(); 
     } 

     static void application_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e) 
     { 
      LogAndClose("Global exception: " + e.Exception.ToString()); 
     } 

     public static void Log(string text) 
     { 
      try 
      { 
       System.IO.File.AppendAllText(Environment.CurrentDirectory + "\\Log.txt", 
        "[" + DateTime.Now.ToString("MM/dd/yy HH:mm:ss") + "] " + text + "\r\n"); 
      } 
      catch { } 
     } 

     public static void LogAndClose(string text) 
     { 
      Log(text); 

      try 
      { 
       Application.Current.Shutdown(); 
      } 
      catch { } 
     } 
    } 
+0

自第一天起,我们就已经为处理调度程序和应用程序域的未处理异常提供了处理程序,并且已经在操作中看到了它们几次。这里没有运气。对于它的价值,我们注册监听器到Application.Current.DispatcherUnhandledException和AppDomain.CurrentDomain.UnhandledException – 2012-03-09 15:55:24

-2

尝试使用ANTS profiler来查看是否有内存泄漏。只需要他们提供的2周试用版,你就可以轻松找到答案。

+0

内存泄漏如何导致这种情况? – svick 2012-03-18 11:03:42

+0

这似乎不是内存泄漏,因为问题在系统干净启动后可以重复使用。 – 2012-03-22 00:33:34

0

您是否尝试过远程调试生产系统?

你需要远程调试是什么:

  • 部署msvcmon.exe
  • 您的开发和生产系统
  • 之间的网络连接,确保代码的本地和远程版本保持同步。您也可以在您的开发机器上构建,并且xcopy将调试版本部署到远程机器上。如果它是纯粹的.net代码,那很简单。如果您还有C++代码,则应确保C++ dll的调试版本位于生产计算机上。或者,构建发行版本和远程调试。
  • 设置用于连接的用户帐户。这实际上有点棘手。 Google remote debugging credentials获得一些提示。
  • 不要忘记禁用所有防火墙!

您可以附加到已经运行的进程,但您也可以从visual studio中启动应用程序。

如果您的开发系统位于远离生产系统的位置,请使用笔记本电脑和远程桌面将您的开发人员工作室带到生产系统。我经常这样做。两人之间的距离甚至五米都很烦人。

我可以详细说明一下,如果有兴趣,或者如果您遇到麻烦设置连接。

祝你好运!