应用程序在Visual Studio外冻结。从Visual Studio启动时它可以工作

时间:2012-06-05 09:31:44

标签: c# visual-studio-2010 visual-studio-2008 freeze

慢慢地,我工作过度......

我有一个庞大的应用程序,包括线程,定时器,调用(不是BeginInvoke,因此它是同步的)和Application.DoEvents。

在这里发帖太多了,我不知道问题究竟在哪里。

我的每一种方法都在尝试捕获。每次捕获都会被记录下来。

如果我从Visual Studio(F5)启动应用程序或通过Ants进行性能分析,则没有问题。应用程序运行了几天。 但是,只要我通过Windows资源管理器启动相同的调试版本,它就会每隔几个小时冻结一次。它会毫无例外地冻结。 如果我将visual studio附加到此应用程序并将其中断,它将在Application.Run上停止(new Form1());

我真的很困惑,也不知道要修复它。

这是一个.net 3.5 winforms应用程序

看起来这里有一个线程挂起:

if (grabber.InvokeRequired)
{
    Console.WriteLine("grabber.InvokeRequired");
    this.Invoke((MethodInvoker) delegate { grabber.Navigate("http://www.google.de"); }); // <-- hang
}
else
{
    grabber.Navigate(ig.StartUrl);
}

此代码段是计时器事件的一部分

_timeout = new System.Timers.Timer(10000);
_timeout.Elapsed += new ElapsedEventHandler(OnWatchDogBark);

修改

DoEvents()的示例。这是在lock()和调用

grabber.DocumentCompleted -= grabber_DocumentCompleted;
grabber.Navigate("http://www.google.de");

while (grabber.ReadyState != WebBrowserReadyState.Complete)
{
    timeout--;
    Application.DoEvents();
    Thread.Sleep(200);

    if (timeout < 0)
    {
        timeout = 50;
        grabber.Navigate("http://www.google.de");
    }
}

目前我使用的是System.Windows.Forms.Timer和一些锁,但没有任何改进。

好的,我用WinDbg获取了一些信息

编辑:14.06.2012

!线程

                                      PreEmptive   GC Alloc           Lock
       ID OSID ThreadOBJ    State     GC       Context       Domain   Count APT Exception
   0    1 37ec 007cab18      6020 Enabled  00000000:00000000 007c8510     0 STA System.ArgumentException (02762ba8)
   2    2 85b8 007d7c38      b220 Enabled  00000000:00000000 007c8510     0 MTA (Finalizer)
XXXX    3    0 06e9f548      9820 Enabled  00000000:00000000 007c8510     0 Ukn
  21    5 3464 0d6dc598   200b020 Enabled  28cb5820:28cb5fe8 007c8510     0 MTA
  22    6 62b0 0d6db9e0   200b220 Enabled  00000000:00000000 007c8510     0 MTA
  23    7 8e58 0d6db5f8    80a220 Enabled  00000000:00000000 007c8510     0 MTA (Threadpool Completion Port)
XXXX    4    0 06f62d40   1801820 Enabled  00000000:00000000 007c8510     0 Ukn (Threadpool Worker)
XXXX    f    0 132a3290   1801820 Enabled  00000000:00000000 007c8510     0 Ukn (Threadpool Worker)
XXXX   10    0 132a3678   1801820 Enabled  00000000:00000000 007c8510     0 Ukn (Threadpool Worker)
XXXX    e    0 132a26d8   1801820 Enabled  00000000:00000000 007c8510     0 Ukn (Threadpool Worker)
XXXX    9    0 0d6db210   1801820 Enabled  00000000:00000000 007c8510     0 Ukn (Threadpool Worker)

!DLK

Examining SyncBlocks...
Scanning for ReaderWriterLock instances...
Scanning for holders of ReaderWriterLock locks...
Scanning for ReaderWriterLockSlim instances...
Scanning for holders of ReaderWriterLockSlim locks...
Examining CriticalSections...
Could not find symbol ntdll!RtlCriticalSectionList.
No deadlocks detected.

4 个答案:

答案 0 :(得分:8)

可能是后台线程中可能出现的死锁。 尝试查看可能阻止您的应用的其他线程。

Toolbar -> Debug -> Windows -> Threads

http://msdn.microsoft.com/en-us/library/w15yf86f.aspx

应该有多个线程,如果你双击一个,你会看到它停止你的应用程序的行。

如果你的代码中有这一行:

Control.CheckForIllegalCrossThreadCalls = false;

再次将其设置为true。导致死锁的可能原因是后台线程访问控件。

而不是从背景线程写出来。

button1.Text = "hello"

写下这个。

this.Invoke(() => button1.Text = "hello");

答案 1 :(得分:3)

如果它冻结,你可能会看到僵局。我发现找到死锁的最好方法之一是使用崩溃转储和sosex。

这是一篇关于使用这种技术的好文章(它是asp.net,但适用相同的原则):http://blogs.msdn.com/b/tess/archive/2010/04/27/debugging-a-classic-readerwriterlock-deadlock-with-sosex-dll.aspx

让应用运行直到它冻结,然后进行挂起转储:http://blogs.msdn.com/b/tess/archive/2006/10/16/net-hang-debugging-walkthrough.aspx

答案 2 :(得分:0)

调用很危险,很容易以意想不到的方式导致死锁,我建议替换

this.Invoke((MethodInvoker)...

this.BeginInvoke((MethodInvoker)...

不会阻止调用者,可能会解决问题。

编辑如果没有,你将需要等到它死锁,然后使用windbg查看你死锁的原因。

答案 3 :(得分:0)

从VS运行时,它会注入一个调试器线程,这会改变一些消息路由。对于正在等待队列中的消息的某些内容,您可能遇到Invoke(...)阻塞问题,但在调试器下,win消息的处理顺序不同。

IIUC你不需要使用System.Windows.Forms.Timer锁,因为它使用win消息泵,所以定时器事件总是在GUI线程上处理(除非你的应用程序中的其他东西在TheadPool上运行代码或在专用背景线程。)

因此,您的示例代码中没有任何内容涉及线程,除非Web浏览器控件在后台线程上触发其事件(在这种情况下,使用BeginInvoke()将这些事件POST回UI线程)。一旦你在主UI线程上运行所有应用程序控件,就删除锁(作为调试辅助工具)。请发布有关后台处理的更多信息以及迄今为止的任何结果。