C# .net所有线程都挂起并被阻止
我的问题是:为什么在.NETWPF应用程序中,通常所有线程都会被阻塞并挂起 我们生成了一个WPF.Net应用程序。一些用户报告主线程偶尔会冻结。通常的情况是:C# .net所有线程都挂起并被阻止,c#,wpf,multithreading,garbage-collection,C#,Wpf,Multithreading,Garbage Collection,我的问题是:为什么在.NETWPF应用程序中,通常所有线程都会被阻塞并挂起 我们生成了一个WPF.Net应用程序。一些用户报告主线程偶尔会冻结。通常的情况是: 应用程序工作约1-3小时,没有任何问题 应用程序偶尔会在大约5-15秒内失去响应,每小时3-10次 应用程序重启没有帮助 我们强烈怀疑,这不仅是UI线程被阻塞,而且所有其他线程也被阻塞 我们添加了一个计时器,它每4秒将日期时间写入文本文件,并在文件中获得以下输出: 11/21/2015 10:55:10 11/21/2015 10:55:
日期时间写入文本文件,并在文件中获得以下输出:
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();
}
}
应用程序是否间歇性地在主UI线程上处理本应在后台线程上运行的操作?由于网络延迟、数据库问题等原因,可能会出现此类问题。如果应用程序重新启动没有帮助,则可能是有一个进程挂起保存资源,如文件,因此,新的应用程序进程在尝试访问它时挂起。你能在任务管理器中看到这个过程并杀死它吗?@KosalaW是的,我们有很多数据库和网络请求。你能详细解释一下它是如何导致所有线程冻结的吗?@AndrewPlakhotnyi如果你试图在不使用异步方法的情况下检索或执行长时间运行的数据库进程,它将完全冻结你的UI线程。我想这就是你们系统中正在发生的事情。你可以做很多事情。使用适当的登录机制,识别所有缓慢的C#方法、存储的进程、web服务调用等。使用C#stop watch获取开始和结束时间。然后努力改进它们。完成后,尝试将它们转换为异步、后台线程等。将所有内容转换为异步可能会带来工作流问题。只要注意它们。