11

ゆっくりと私は働き過ぎです...

スレッド、タイマー、invoke(BeginInvokeではないため、同期)、およびApplication.DoEventsを備えた巨大なアプリケーションがあります。

ここに投稿するには多すぎて、問題が実際にどこにあるのかわかりません。

私のすべての方法は、トライキャッチの中にあります。すべてのキャッチがログに記録されます。

Visual Studio(F5)からアプリケーションを起動した場合、またはAntsを介してアプリケーションをプロファイリングしている場合は、問題はありません。アプリケーションは数日から実行されます。しかし、Windowsエクスプローラーで同じデバッグバージョンを開始するとすぐに、数時間ごとにフリーズします。例外なくフリーズします。Visual Studioをこのアプリケーションに接続して壊すと、Application.Run(new Form1());で停止します。

私は本当に混乱していて、それを修理する考えがありません。

これは、.net3.5winformsアプリケーションです。

ここに1つのスレッドがぶら下がっているように見えます:

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()とinvokeにあります

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を使用しました

編集:2012年6月14日

!スレッド

                                      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

4 に答える 4

8

バックグラウンドスレッドでデッドロックが発生している可能性があります。アプリをブロックする可能性のある他のスレッドを調べてみてください。

Toolbar -> Debug -> Windows -> Threads

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

複数のスレッドがあるはずです。1つをダブルクリックすると、アプリを停止している行が表示されます。

そして、あなたがあなたのコードのこの行をしているなら:

Control.CheckForIllegalCrossThreadCalls = false;

もう一度trueに設定します。デッドロックの考えられる原因は、バックグラウンドスレッドアクセスコントロールです。

バックグラウンドスレッドからこれを書く代わりに。

button1.Text = "hello"

これを書いてください。

this.Invoke(() => button1.Text = "hello");
于 2012-06-05T09:41:31.060 に答える
3

凍結している場合は、デッドロックが発生している可能性があります。デッドロックを見つけるために私が見つけた最良の方法の1つは、クラッシュダンプと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

于 2012-06-07T14:23:56.293 に答える
0

呼び出しは危険であり、予期しない方法でデッドロックを簡単に引き起こす可能性があります。交換することをお勧めします

this.Invoke((MethodInvoker)...

this.BeginInvoke((MethodInvoker)...

これは発信者をブロックせず、おそらく問題を解決します。

そうでない場合は、デッドロックが発生するまで待ってから、windbgを使用してデッドロックが発生した理由を確認する必要があります。

于 2012-06-13T17:49:46.183 に答える
0

VSから実行すると、デバッガスレッドが挿入され、メッセージのルーティングが変更されます。Invoke(...)キュー内のメッセージを待機しているもののブロックに問題がある可能性がありますが、デバッガーでは、winメッセージは異なる順序で処理されます。

IIUCはwinメッセージポンプを使用するため、System.Windows.Forms.Timerでロックする必要はありません。したがって、タイマーイベントは常にGUIスレッドで処理されます(アプリ内の他の何かがTheadPoolまたは専用のバックグラウンドスレッドでコードを実行している場合を除く) )。

したがって、サンプルコードには、Webブラウザーコントロールがバックグラウンドスレッドでイベントを発生させない限り、スレッド化は含まれません(この場合、イベントをUIスレッドにPOSTしますBeginInvoke())。メインUIスレッドですべてのアプリケーションコントロールを実行したら、(デバッグの補助として)ロックを解除します。バックグラウンド処理とこれまでの結果に関する詳細情報を投稿してください。

于 2012-06-13T23:50:32.833 に答える