Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 当windows布局因在另一个线程中创建ReportViewr而发生更改时,在非常复杂的WPF应用程序中挂起未知位置_C#_.net_Wpf_Reportviewer_Freeze - Fatal编程技术网

C# 当windows布局因在另一个线程中创建ReportViewr而发生更改时,在非常复杂的WPF应用程序中挂起未知位置

C# 当windows布局因在另一个线程中创建ReportViewr而发生更改时,在非常复杂的WPF应用程序中挂起未知位置,c#,.net,wpf,reportviewer,freeze,C#,.net,Wpf,Reportviewer,Freeze,我有一个带有非常复杂XAMLs的WPF应用程序,我需要一种方法来知道我的应用程序挂起的点,当我尝试暂停执行时,应用程序似乎没有挂起,指针将在这一行: System.Windows.Application myApp; . . . . myApp.Run(); // <== this line 或 或 我的问题是: 1-更改窗口布局(调整任务栏大小或移动任务栏)与未添加到任何可视树的报表查看器之间有什么关系,为什么这会导致我的应用程序挂起 2-如何确定悬挂位置 3-有时应用程序将在几分钟(

我有一个带有非常复杂XAMLs的WPF应用程序,我需要一种方法来知道我的应用程序挂起的点,当我尝试暂停执行时,应用程序似乎没有挂起,指针将在这一行:

System.Windows.Application myApp;
.
.
.
.
myApp.Run(); // <== this line

我的问题是:

1-更改窗口布局(调整任务栏大小或移动任务栏)与未添加到任何可视树的报表查看器之间有什么关系,为什么这会导致我的应用程序挂起

2-如何确定悬挂位置

3-有时应用程序将在几分钟(3-5分钟)内恢复,但有时应用程序仍会挂起数小时而无法恢复,原因是什么

4-在这种情况下,如何确定导致应用程序挂起的组件或配置


顺便说一句,这对其他人来说是一个非常有用的问题,如果解决了,我们花了大量时间来检测它,但是没有得到导致挂起的确切原因,再加上ReportViewer

在VS调试器中暂停后,打开Debug/Windows菜单上的Threads窗口。将它们全部选中并冻结(从关联菜单中)。然后双击每个线程以查看其卡在何处。此外,右键单击调用堆栈并显示外部代码。

简单-不要在其他线程中创建ReportViewer。绑定到一个UI层次结构中的所有元素必须来自UI线程


在创建操作中,调用回UI线程以在UI线程中进行实际创建。

在这种情况下,我喜欢使用几种技巧:

我已经有了这个答案

但这也应该涵盖您的问题,它会记录每个操作,直到CLR崩溃

IntelliTraceEvents和Call Information是一个惊人的技巧,它可以精确地找到发生挤压之前发生的事情

工具->调试->常规->启用.Net Framework调试

+

工具->智能->智能跟踪事件和呼叫信息

+

工具->智能->在此目录中设置StorIntelliTace录制

然后选择一个目录

应该允许您进入.net代码并跟踪每个函数调用。我在一个小样本项目上试用了它,效果很好

在每个调试会话之后,它将创建调试会话的记录。如果我没弄错的话,即使CLR死了,它也会保存在set目录中

这应该允许您在CLR崩溃之前访问extact调用

第二个技巧

生产中可能用到的是一个很棒的框架,名为
PostSharp

请注意本教程:

如前所述使用postsharp后

您可以为系统中的每一个函数记录输入时间、终止时间以及异常是否通过日志记录所有变量


使用几十行代码完成所有这些操作。

我将尽可能完整地回答您的问题:

ReportViewer控件是Windows窗体控件,Windows窗体有一个问题,在适当的情况下可能会导致UI线程锁定,从而导致应用程序挂起

Windows发布WM_SETTINGCHANGED消息时,会触发事件
System.Win32.SystemEvents.UserPreferenceChanged
。一些Windows窗体控件,包括
ReportViewer
在系统设置更改时侦听此事件以更新自身

与其他常规事件不同,
UserPreferenceChanged
事件将使用订阅线程的SynchronizationContext调用每个处理程序。因此,如果ReportViewer是在主UI线程(WPF中的Dispatcher线程)以外的线程上创建的,则事件触发代码将尝试执行调用,并等待调用完成,这在另一个线程上永远不会发生,从而冻结UI

要确定挂起的位置,您可以轻松禁用选项Enable Just my code in Visual Studio->Tools->Options->Debugging,当挂起发生时,只需将VS调试器连接到挂起的应用程序,这将显示应用程序挂起在UserPreferenceChanged事件处理中的WaitOne调用

您可以在以下文章中阅读有关此挂起的更多信息:


您可以尝试使用诸如Red Gate ANTS之类的代码分析工具(我认为它们仍然可以免费试用)。这至少会让你知道代码花了多少时间-它可能不会发现潜在的死锁(可能是长时间运行的任务或死锁等等)尝试了几天,我没有得到任何有用的信息!尝试了debug diag和其他通用windows调试工具,但没有找到我的应用程序挂起的特定点,我非常确定,这是因为某些错误的XAML,我需要工具来查看分派器挂起在XAML中的点。这会发生在多台计算机上吗?是的,在许多具有多种配置的计算机上!挂起线程时发布线程的调用堆栈。确保包含对外部代码的调用。没有告诉我导致挂起的原因,主线程处于睡眠状态,加入,但不知道在哪里!我知道,我已经这样做了,正如我在回答中提到的,问题是我担心与reportviewer结合导致挂起的主要原因,挂起可能在其他情况下提出,因为ReportViwer以外的组件!我需要知道主要原因。或者在我的应用程序中找到主要原因的方法,如果我找到了,我会在这里说明。主要原因仍然是一样的-STA线程是强制性的。在过去30年中,当你忽略任何windows UI的基本构建块时,每个组件都可能显示出这种行为。我知道我在某些方面有一个错误,我需要知道,在创建reportview时,挂起行为并不存在
        new Action(() =>
        {
            ReportViewer rv = new ReportViewer();
        }).BeginInvoke(null, null);
        new Action(() =>
        {
            ReportViewer rv = new ReportViewer();
            rv.Dispose();
        }).BeginInvoke(null, null);
        new Action(() =>
        {
            ReportViewer rv = new ReportViewer();
            rv.LocalReport.ReleaseSandboxAppDomain();
            rv.Dispose();
        }).BeginInvoke(null, null);