WPF应用程序错误和.Net框架修复

时间:2012-02-11 17:09:23

标签: .net wpf prism .net-framework-version

背景: 我在Windows XP和Windows PosReady 2009 PC上运行了基于.Net 3.5 WPF“Prism”的应用程序。该应用程序运行在每晚关闭的PC上(通过C#调用“shutdown.exe”)并在早上启动(通过局域网唤醒)。该应用程序是基于触摸的(使用ELO触摸屏),没有连接鼠标或键盘,用户无法访问Windows。

问题: 我们偶尔会看到两件事之一发生的问题;要么应用程序似乎没有正确加载,我们看到一个空白的白色表单显示,或它停止响应触摸。通过查看我们的(log4net)日志,我们可以看到我们仍在处理触摸事件并在两种情况下都将其记录下来。通常这在切换视图时会发生,我们也会在日志中看到Prism RegionManager正在删除并正确添加视图。

疑难解答: 该应用程序使用Clonezilla应用的图像在大约100台PC上运行,这种情况只是偶尔发生。由于它并未在所有PC上发生,并且在事件查看器中没有记录任何异常或任何指示问题,因此我们采用了更多的PC和操作系统级修复程序。具体来说,我们尝试重新启动应用程序和PC偶尔短期成功 - 这意味着有时应用程序将在重新启动后正常运行,但最多只能持续几个小时。我们也假设应用程序已经被破坏,我们已经删除并重新安装它,但没有成功。

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

结论: 由于这似乎解决了这个问题,当没有别的办法时,我们似乎在某种程度上破坏了GAC的框架DLL - 无论是通过代码还是PC上的启动/关闭程序。

问题: 这导致了许多问题:

  • 关于如何进一步确定问题根源的任何想法?
  • 关于我们如何防止此问题的任何想法?
  • 关于潜在问题可能是什么的任何想法?

感谢您的帮助。

5 个答案:

答案 0 :(得分:2)

我们终于能够获得展示此行为的生产计算机,并通过一系列故障排除步骤,包括向Microsoft发送转储文件,问题已找到。

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

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

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

感谢大家的意见和建议。

答案 1 :(得分:0)

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

您可以在http://social.msdn.microsoft.com/Forums/en-IE/windowsaccessibilityandautomation/thread/6c4465e2-207c-4277-a67f-e0f55eff0110

了解有关该问题的更多信息

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

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

答案 2 :(得分: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 { }
        }
    }

答案 3 :(得分:0)

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

远程调试需要:

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

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

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

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

祝你好运!

答案 4 :(得分:-2)

尝试使用ANTS profiler查看是否有内存泄漏。您可以轻松找到他们提供的2周试用版。