我的问题是:为什么一般所有线程都会被阻止并挂在.Net wpf应用程序中?
我们生成WPF .Net应用程序。一些用户报告偶尔会冻结主线程。通常的情况是:
我们强烈怀疑这不只是UI线程被阻止,而且所有其他线程也被阻止。
我们添加了一个计时器,每隔4秒将DateTime.Now
写入文本文件,并在文件中获得以下输出:
11/21/2015 10:55:10
11/21/2015 10:55:14
11/21/2015 10:55:18
11/21/2015 10:55:22
11/21/2015 10:55:29
11/21/2015 10:55:37
11/21/2015 10:55:41
11/21/2015 10:55:45
11/21/2015 10:55:49
因此,计时器线程在第29秒和第37秒之间被阻止。
首先,我们怀疑垃圾收集器执行完全阻塞收集。但是,我们添加了GC集合通知程序,但未收到GC的任何通知。
以下是我们的GC集合日志记录的样子:
public class GCNotifier: IDisposable
{
private readonly int _notificationLoopIntervalMs;
public bool IsEnabled = true;
public GCNotifier(int notificationLoopIntervalMs = 50)
{
_notificationLoopIntervalMs = notificationLoopIntervalMs;
GC.RegisterForFullGCNotification(10,10);
Task.Factory.StartNew(NotificationLoop);
}
void NotificationLoop()
{
while(IsEnabled)
{
var status = GC.WaitForFullGCApproach();
if (status == GCNotificationStatus.Succeeded)
//Log GC.Collect is approaching here
else
continue;
status = GC.WaitForFullGCComplete();
if (status == GCNotificationStatus.Succeeded)
//Log GC collection completed
Thread.Sleep(_notificationLoopIntervalMs);
}
}
public void Dispose()
{
IsEnabled = false;
GC.CancelFullGCNotification();
}
}