2017-06-01 56 views
4

我們有一個使用異步/等待模式的複雜ASP.Net核心應用程序。該應用程序最近停止響應,我們爲它做了內存轉儲。我們懷疑有一些異步操作會導致應用程序停滯不前,但不知道是哪一個。在爲Web應用程序進行內存轉儲後,由於使用async/await,線程返回到線程池,因此可以看到很少的正在運行的線程。 問題是,是否有可能在內存轉儲中列出正在運行的任務以及它們運行的​​位置,以便我可以確定哪些異步操作會使應用程序停滯不前?對於同步阻止調用很容易 - 只需列出所有活動線程的調用堆棧即可。但對於異步操作,它不再起作用。 (添加更多的痕跡是一種可能的方法,但情況是我們不能保證我們有足夠的痕跡來執行應用程序中的每個異步操作以及它是從屬庫。)如何在.net內存轉儲中列出正在運行的任務

例如,如果ASP.Net Core應用程序卡在這樣的一些代碼中,我怎麼能從內存轉儲中告訴它?

public async Task SomeBadMethodInADependentLibrary() 
{ 
    TaskCompletionSource<int> tcs = new TaskCompletionSource<int>(); 
    await tcs.Task; 
} 

回答

4

您當然可以在堆中找到任務對象,並使用SOS命令手動開始分析它們,例如,像這樣開始調試會話:從我的觀點是使用Mex (Github)!TaskTriage命令點

0:013> !dumpheap -stat -type Task 
Statistics: 
     MT Count TotalSize Class Name 
[...] 
71e03f28  4   160 System.Threading.Tasks.Task 
Total 28 objects 

0:013> !dumpheap -mt 71e03f28 
Address  MT  Size 
022bd900 71e03f28  40  
[...] 

0:013> !do 022bd900 
Name:  System.Threading.Tasks.Task 
MethodTable: 71e03f28 
EEClass:  719cd6e0 
Size:  40(0x28) bytes 
File:  C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll 
Fields: 
     MT Field Offset     Type VT  Attr Value Name 
71df1638 40019cd  1c   System.Int32 1 instance  3 m_taskId 
71defb44 40019ce  4  System.Object 0 instance 022bd8e0 m_action 
[...] 

0:013> !DumpObj 022bd8e0 
Name:  System.Action 
MethodTable: 71e0588c 
EEClass:  719357b8 
Size:  32(0x20) bytes 
File:  C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll 
Fields: 
     MT Field Offset     Type VT  Attr Value Name 
71defb44 40002b5  4  System.Object 0 instance 022bd8e0 _target 
71defb44 40002b6  8  System.Object 0 instance 00000000 _methodBase 
71df2bdc 40002b7  c  System.IntPtr 1 instance 4b00e64 _methodPtr 
71df2bdc 40002b8  10  System.IntPtr 1 instance 4e0c30 _methodPtrAux 
[...] 

0:013> !u 4e0c30 
Unmanaged code 
004e0c30 e833df8372  call clr!PrecodeFixupThunk (72d1eb68) 
[...] 

,現在是開始成爲累贅......

最方便的方式(在WinDbg中):

0:013> !TaskTriage 
Normal Mode - not showing successful Tasks 
Address Target  Status      Method        Exceptions 
================================================================================================== 
022bd900 | 022bd8e0 | TASK_STATE_DELEGATE_INVOKED | Demo.Program.printMessage()  |  <none> 
022bd974 | 022bd868 | TASK_STATE_DELEGATE_INVOKED | Demo.Program+<>c.<Main>b__0_0() |  <none> 
022bd9bc | 022bd868 | TASK_STATE_STARTED   | Demo.Program+<>c.<Main>b__0_1() |  <none> 
022bda04 | 022bd868 | TASK_STATE_STARTED   | Demo.Program+<>c.<Main>b__0_2() |  <none> 
================================================================================================== 
Address Target  Status      Method        Exceptions 

使用的WinDbg在Visual Studio中的想法是好的,因爲這兩個VS2015和VS2017將無法給從轉儲文件相同的結果:

Result in VS2015 and VS2017

相關問題