Visual Studio调试器无法跳转到.NET框架源代码

8

我正在进行这个简单的异步调用。我想跟踪到DownloadDataTaskAsync方法并逐步进入Microsoft .NET框架源代码。

using System;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace WhereIsTheTaskSchedulerHere
{
    class Program
    {
        static void Main(string[] args)
        {
            var task = GetData("http://sathyaish.net");
            var buffer = task.Result;

            var data = Encoding.ASCII.GetString(buffer);

            Console.WriteLine(data);
            Console.WriteLine("\nPress any key to continue...");
            Console.ReadKey();
        }

        async static Task<byte[]> GetData(string url)
        {
            var client = new WebClient();
            var data = await client.DownloadDataTaskAsync(url);
            return data;
        }
    }
}

我在 Reflector 中跟踪代码,直到代码调用了 System.Net.WebClient.DownloadBits 方法。如果该调用意味着要异步执行,则该方法通过调用 System.Net.WebRequest 类上的异步编程模型 (APM) 方法 BeginGetResponse 进一步在线程池线程上安排工作。这是 Reflector 中 DownloadBits 方法的代码。
private byte[] DownloadBits(WebRequest request, Stream writeStream, CompletionDelegate completionDelegate, AsyncOperation asyncOp)
{
    WebResponse response = null;
    DownloadBitsState state = new DownloadBitsState(request, writeStream, completionDelegate, asyncOp, this.m_Progress, this);
    if (state.Async)
    {
        request.BeginGetResponse(new AsyncCallback(WebClient.DownloadBitsResponseCallback), state);
        return null;
    }
    response = this.m_WebResponse = this.GetWebResponse(request);
    int bytesRetrieved = state.SetResponse(response);
    while (!state.RetrieveBytes(ref bytesRetrieved))
    {
    }
    state.Close();
    return state.InnerBuffer;
}

所以,我在Visual Studio中设置了两个断点:

1)一个在Sytem.Net.WebClient.DownloadBits方法上;另一个在

enter image description here

2) 关于System.Net.WebRequest.BeginGetResponse方法。

enter image description here

enter image description here

我已经仔细检查了以下内容。
1)我正确配置了“Visual Studio工具->选项”对话框中的“调试”设置,允许调试器步入.NET框架源代码。

enter image description here

2) 我已经启用了将调试符号下载和缓存到正确位置的功能。

enter image description here

3)我仔细检查了位置,并发现我的代码引用的所有程序集以及特别是 System.dll 都具有调试符号,这些符号包含我设置断点的方法。

enter image description here

然而,当我打开调试功能运行代码时,它抱怨找不到System.dll的调试符号。所以,我点击了“加载”按钮,让它从Microsoft符号服务器在运行时下载它们。

enter image description here

即使如此,在它断在DownloadBits方法时,我从调用堆栈窗口和从它打印在输出窗口中的消息中看到,它并没有显示或步入该方法的源代码。

enter image description here

我在 调用堆栈窗口 中右键单击 DownloadBits 方法的堆栈帧,想要点击 加载符号 菜单项,但它并不存在。因此,转到源代码 菜单项也被禁用了。

enter image description here

我清除了缓存并让它重新下载所有程序集,但这也没有帮助。

我正在使用Visual Studio Community Edition 2015,我的程序针对.NET框架的v4.5.2版本,并且我以前已经多次使用此设置进入过.NET源代码程序集。

我错过了什么?


2
参考源网站自4月22日左右通过Windows Update提供的.NET更新以来已经失去同步。这是一个非常常见的错误,请根据this post中提供的提示进行诊断。 - Hans Passant
@HansPassant 非常感谢。在“模块”窗口的上下文菜单中点击“符号加载信息”,“符号加载信息”对话框报告说它能够从我的本地缓存中加载System.dll的调试符号。然而,它仍然无法进入源代码。 - Water Cooler v2
@HansPassant 顺便说一下,我为用户反馈项目投了3票。 :-) - Water Cooler v2
@HansPassant,我刚刚注意到在我的应用程序域中加载的程序集在模块窗口中显示版本列为4.6.xxx。即使我针对框架的v4.5.2,System.dll的版本也是4.6.1075.xxxx。但是,它被加载的路径是C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0.0__b77a5c561934e089\System.dll。这有关系吗? - Water Cooler v2
2
你所针对的版本并不重要,它只是确保你可以在仅安装了4.5.2且从未更新过的机器上运行程序。你总是使用实际安装在你的机器上的版本来执行程序。目前大多数人都使用4.6.1,这样你就无法受益于添加在4.6和4.6.1中的错误修复和设计更改,但它会在运行时检查你所针对的版本。 - Hans Passant
1个回答

2
您可以尝试使用dotPeek的即时符号服务器。它将反编译程序集并充当普通符号服务器。
在dotPeek中设置符号服务器(工具 -> 符号服务器)。将符号服务器地址复制到剪贴板。
将此符号服务器添加到Visual Studio中并删除其他符号服务器(或仅禁用它)。
请注意,加载所有.NET程序集可能需要很长时间。您可以通过在dotPeek中选择在程序集资源管理器中打开的程序集选项进行调整。
额外说明:https://hmemcpy.com/2014/07/how-to-debug-anything-with-visual-studio-and-jetbrains-dotpeek-v1-2/

哇!非常感谢,感谢,感谢,感谢,感谢您。我已经在这个领域奋斗了多年。 - Water Cooler v2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接