.net所有线程都挂起并被阻止

时间:2015-11-21 10:27:26

标签: c# wpf multithreading garbage-collection

我的问题是:为什么一般所有线程都会被阻止并挂在.Net wpf应用程序中?

我们生成WPF .Net应用程序。一些用户报告偶尔会冻结主线程。通常的情况是:

  1. 应用程序工作约1-3小时没有任何问题。
  2. 每小时3-10次约5-15秒,应用程序偶尔会无响应。
  3. Applcation restart无效。
  4. 我们强烈怀疑这不只是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();
            }
        }
    

0 个答案:

没有答案