8

I have this simple async call I am making. I want to follow the call to the DownloadDataTaskAsync method and step through into the Microsoft .NET framework source code.

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;
        }
    }
}

I followed the call in Reflector until the point that the code calls System.Net.WebClient.DownloadBits method. If the call was meant to be executed asynchronously, this method further schedules the work on a threadpool thread by calling the Asynchronous Programming Model (APM) method BeginGetResponse on the System.Net.WebRequest class.

Here is the code of the DownloadBits method from Reflector.

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;
}

So, I set up two breakpoints in Visual Studio:

1) One on the Sytem.Net.WebClient.DownloadBits method; and the other

enter image description here

2) On the System.Net.WebRequest.BeginGetResponse method.

enter image description here

enter image description here

I double-checked the following.

1) That I configured the Debugging settings in the Visual Studio Tools -> Options dialog correctly allowing the debugger to step through .NET framework source.

enter image description here

2) That I had enabled the downloading and caching of debug symbols to a proper location.

enter image description here

3) I double-checked the location and saw that there were Debug symbols for all the assemblies my code referenced and particularly for the System.dll which had the methods that my breakpoints were set on.

enter image description here

However, when I ran the code with debugging on, it complained that it couldn't find the debug symbols for System.dll. So, I clicked the Load button to let it download them at runtime from the Microsoft Symbol Server.

enter image description here

Even then, while it did break at the DownloadBits method, as I saw from the Call Stack Window and from the message it printed in the Output Window that I had asked it to print while setting up the breakpoint, it did not show or step into the source of that method.

enter image description here

I right-clicked the stack-frame of the DownloadBits method in the Call Stack Window to click the Load Symbols menu item, but it wasn't there. Consequently, the Go to Source Code menu item was also disabled.

enter image description here

I cleared the cache and let it download all assemblies afresh but that hasn't helped either.

I am using Visual Studio Community Edition 2015 and my program is targeting v4.5.2 of the .NET framework and I have previously been able to step into .NET source assemblies using this set up many times.

What have I been missing?

Water Cooler v2
  • 32,724
  • 54
  • 166
  • 336
  • 2
    The reference source web site has been out of sync since a .NET update delivered through Windows Update around April 22nd. A very common mishap, diagnose with the hints provided in [this post](http://stackoverflow.com/a/27655501/17034).. – Hans Passant Jun 04 '16 at 17:50
  • @HansPassant Thank you very much. Upon clicking **Symbol Load Information** from the context menu in the **Modules** window, the **Symbol Load Information** dialog reports that it was able to load the debug symbols for `System.dll` from my local cache. However, it still does not step into the source. – Water Cooler v2 Jun 04 '16 at 20:56
  • @HansPassant BTW, upvoted the User Voice item by 3 votes. :-) – Water Cooler v2 Jun 04 '16 at 20:58
  • @HansPassant I just noticed in the **Modules** window that the assemblies that are loaded in my appdomain have the **Version** column displaying 4.6.xxx in many cases. `System.dll` is version 4.6.1075.xxxx even though I am targeting v4.5.2 of the framework. However, the path from where it is loaded is *C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0.0__b77a5c561934e089\System.dll*. Does that matter? – Water Cooler v2 Jun 04 '16 at 22:03
  • 2
    The version you target does not matter, it merely ensures that you can run your program on a machine that only has 4.5.2 installed and was never updated. You always execute your program with the version you have actually installed on your machine. Which is 4.6.1, right now it is for just about everybody that keeps their machine updated. You can't benefit from bug fixes and design changes that were added in 4.6 and 4.6.1, it does check at runtime which version you targeted. – Hans Passant Jun 04 '16 at 22:19

1 Answers1

2

You can try to use an on-the-fly Symbol Server with dotPeek. It will decompile the assemblies and act as a normal Symbol Server.

Setup the symbol server in dotPeek (Tools -> Symbol Server). Copy the Symbol Server address to the clipboard.

Add this Symbol Server to Visual Studio and remove the other one (or just disable it).

Be aware, it can take a long time to load all .NET assemblies. You can tweak it by choosing Assemblies opened in the Assembly Explorer option in dotPeek.

Extra Instructions: https://hmemcpy.com/2014/07/how-to-debug-anything-with-visual-studio-and-jetbrains-dotpeek-v1-2/

diox8tony
  • 348
  • 3
  • 13
Dávid Molnár
  • 10,673
  • 7
  • 30
  • 55