簡體   English   中英

在 c#/Xamarin/Android 如何獲取所有托管線程的堆棧跟蹤?

[英]In c#/Xamarin/Android How do I get the stack trace for all managed threads?

我正在嘗試診斷為什么我的應用程序凍結並且 android 顯示一條應用程序沒有響應的消息。 由於未知原因,當這種情況發生時,應該在 logcat 輸出中顯示的消息不會。

我正在考慮使用https://github.com/nwestfall/Xamarin.ANRWatchDog來了解我的應用程序中發生的情況,如果它變得無響應。 問題是,從 ac#/managed thread 的角度來看,我在調用堆棧中看不到任何東西。

我能找到的所有信息都不適用於 c#/Xamarin/Android 和/或針對桌面/服務器開發的開發。 嘗試獲取線程列表會給我一個列表,但列表中的所有條目都是空的。 即使我可以列出實際線程,如何獲取每個線程的調用堆棧?

var threads = Process.GetCurrentProcess().Threads;

有沒有辦法獲取 Xamarin/Android 應用程序中所有托管線程的當前堆棧跟蹤?

System.Diagnostics.StackTrace() 用於當前線程,但您可能並不關心這一點。

這是獲取其他線程並獲取其堆棧跟蹤的一種方法: 如何獲取非當前線程的堆棧跟蹤?

如果這不起作用,您當然可以使用我很久以前在winforms中成功使用的方法。 這是策略:

  • 確保您的所有工作線程都有一個頂級的 try/catch 日志記錄,您可以訪問
  • 中止工作線程並在日志中查找中止異常!

聽起來很簡單,但會讓你直接崩潰。 您仍然必須讓線程中止它們,請參閱上面 S/O 鏈接中的 threadsampler.Start 方法的前幾行。

如果您的 UI 是響應式的,您可以在復活節彩蛋激活的 devtools 菜單中隱藏此功能,或者在您的配置中激活調試菜單(無論如何,當您的 UI 應用程序變得不平凡時,您會想要!)

不幸的是,由於它被鎖定,您只需要啟動一個后台線程來運行此功能,您可以讓它每秒或 20 次 ping UI,如果它鎖定則中止線程。 策略是在 UI 線程上調用“虛擬函數”: https ://docs.microsoft.com/en-us/dotnet/maui/platform-integration/appmodel/main-thread 並等待它回來,例如,InvokeOnMainThreadAsync,它應該在 5 秒或更短的時間內完成,否則你會采取行動。 應用超時等待它: 異步等待 Task<T> 以 timeout 完成

確保在產品中關閉它!!! 或者可選地,通過開關激活,您可以引導用戶打開。

這是我們多年前在應用領域中使用的模式。

完整傳奇: 如何獲得winform的GUI線程?

我們的應用程序的較新版本在后台線程上完成所有工作,如果花費超過 10 秒,用戶就有機會取消。 然而,這需要使用抽象的 UI,並且團隊在 MVVM 上創建了一個變體。 很有用,因為它允許我們使用所有相同的代碼(包括 UI 代碼)部署厚客戶端和 Web 應用程序。 可能不值得為任何其他應用程序付出努力,如果我不得不這樣做,我會為網絡應用程序使用 JavaScript,並通過科爾多瓦、反應等將其部署到電子和移動設備的桌面。哦,好吧。

您可能超出了這個范圍(提前道歉)但是有Debug\Windows\Threads選項卡,如果我在我的 Xamarin Android 應用程序中故意掛起一個命名線程:

new Thread(hangMe) { Name = "HangMe" }.Start();
void hangMe()
{
    while(true)
    {
        Thread.Sleep(500);
    }
}

如果通過轉到 VS 主菜單Debug\Break All來暫停執行,那么Threads選項卡中可能會有一些有用的調用堆棧信息。

線程選項卡

我明白事情很少這么簡單......

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM