Hide comments in Visual Studio

How often have I wished that there was an option in Visual Studio to hide the comments in the source code. Comments are great, no doubt. And every programmer should well comment his code. However, sometimes they can be a bit annoying and block the sight on the actual code. Mainly if I want to comprehend or refactor a piece of code, it would be nice to have an option to toggle all comments off, especially when it’s my own code. 😉

In short, I wrote a little Add-In for Visual Studio that does just that. Actually it does not really toggle the comments on and off, in fact it sets the text color equal to the background color. It’s probably not the best solution, but it does serve the purpose for now.

It can be downloaded here.

I didn’t make an installer for the Add-In, so you just have to put the unpacked files into your %VSMYDOCUMENTS%\Addins folder where %VSMYDOCUMENTS% usually points to “C:\Users\<UserName>\Documents\Visual Studio 2008”.

You will then see a new button in context menu:

And in the Tools menu to edit the options:

There you can specify what kind of comments should be affected.

Advertisements

Making an asynchronous WebRequest

When downloading large amounts of data a normal synchronous web request, as described in the previous article, may block your current thread. The solution for this is to make an asynchronous web request. To start an asynchronous webrequest WebRequest.BeginGetResponse() has to be called. But before we can do that, we have to write some decent lines of code.

At first we have to create an object that stores the state of the request. To do this we create a new class RequestState:


public class RequestState
{
    public int BufferSize { get; private set; }
    public StringBuilder ResponseContent { get; set; }
    public byte[] BufferRead { get; set; }
    public HttpWebRequest Request { get; set; }
    public HttpWebResponse Response { get; set; }
    public Stream ResponseStream { get; set; }

    public RequestState()
    {
        BufferSize = 1024;
        BufferRead = new byte[BufferSize];
        ResponseContent = new StringBuilder();
        Request = null;
        ResponseStream = null;
    }
}

After that we need to create a Callback method to process the response. This has to be in the form of the AsyncCallback delegate:


    public delegate void AsyncCallback(IAsyncResult ar);

So here’s our method:


private void ResponseCallback(IAsyncResult result)
{
    try
    {
        // Get and fill the RequestState
        RequestState state = (RequestState)result.AsyncState;
        HttpWebRequest request = state.Request;
        // End the Asynchronous response and get the actual resonse object
        state.Response = (HttpWebResponse)request.EndGetResponse(result);
        Stream responseStream = state.Response.GetResponseStream();
        state.ResponseStream = responseStream;

        // Begin async reading of the contents
        IAsyncResult readResult = responseStream.BeginRead(state.BufferRead,
                0, state.BufferSize, new AsyncCallback(ReadCallback), state);
    }
    catch (Exception ex)
    {
        // Error handling
        RequestState state = (RequestState)result.AsyncState;
        if (state.Response != null)
            state.Response.Close();
    }
}

As you can see, we need another Callback method for our asynchronous read operation. We also just could call the responseStream.ReadToEnd() method to get the response data but that would again block the calling thread. So the response should also be read asynchonously.


private void ReadCallback(IAsyncResult result)
{
    try
    {
        // Get RequestState
        RequestState state = (RequestState)result.AsyncState;
        // determine how many bytes have been read
        int bytesRead = state.ResponseStream.EndRead(result);

        if (bytesRead > 0) // stream has not reached the end yet
        {
            // append the read data to the ResponseContent and...
            state.ResponseContent.Append(Encoding.ASCII.GetString(state.BufferRead, 0, bytesRead));
            // ...read the next piece of data from the stream
            state.ResponseStream.BeginRead(state.BufferRead, 0, state.BufferSize,
                new AsyncCallback(ReadCallback), state);
        }
        else // end of the stream reached
        {
            if (state.ResponseContent.Length > 0)
            {
                // do something with the response content, e.g. fill a property or fire an event
                AsyncResponseContent = state.ResponseContent.ToString();
                // close the stream and the response
                state.ResponseStream.Close();
                state.Response.Close();
                OnAsyncResponseArrived(AsyncResponseContent);
            }
        }
    }
    catch (Exception ex)
    {
        // Error handling
        RequestState state = (RequestState)result.AsyncState;
        if (state.Response != null)
            state.Response.Close();
    }
}

Now that we have written all this code, we are finally ready to call WebRequest.BeginGetResponse() and pass in an instance of the RequestState class and the ResponseCallback:


public void MakeWebRequestAsync(string url)
{
    try
    {
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
        request.Method = "GET";
        request.Proxy = null;

        RequestState state = new RequestState();
        state.Request = request;

        IAsyncResult result = request.BeginGetResponse(new AsyncCallback(ResponseCallback), state);
    }
    catch (Exception ex)
    {
        // Error handling
    }
}

Implementing a timeout functionality

When making an asynchronous webrequest the WebRequest.Timeout property will be ignored. So we have to implement our own timeout machanism. The following lines will demonstrate how to accomplish that task.

First we need to register a timeout delegate after the request.BeginGetResponse() call:

public void MakeWebRequestAsync(string url, int timeOut)
{
    try
    {
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
        request.Method = "GET";
        request.Proxy = null;

        RequestState state = new RequestState();
        state.Request = request;

        IAsyncResult result = request.BeginGetResponse(new AsyncCallback(ResponseCallback), state);

        // Timeout comes here
        ThreadPool.RegisterWaitForSingleObject(result.AsyncWaitHandle,
            new WaitOrTimerCallback(TimeOutCallback), request, timeOut, true);
    }
    catch (Exception ex)
    {
        // Error handling
    }
}

In the TimeOutCallback we’re just aborting the webrequest. It looks something like this:


private void TimeOutCallback(object state, bool timedOut)
{
    if (timedOut)
    {
        HttpWebRequest request = state as HttpWebRequest;
        if (request != null)
            request.Abort();
    }
}
public class RequestState { public int BufferSize { get; private set; } public StringBuilder ResponseContent { get; set; } public byte[] BufferRead { get; set; } public HttpWebRequest Request { get; set; } public HttpWebResponse Response { get; set; } public Stream ResponseStream { get; set; }   public RequestState() { BufferSize = 1024; BufferRead = new byte[BufferSize]; ResponseContent = new StringBuilder(); Request = null; ResponseStream = null; } }

WebRequest slow?

I recently tried to do a web request in .NET C#. So I looked it up in the MSDN and wrote down some lines of code and was happy that it worked  straightaway (ok, it’s not very complex anyhow).

It looked something like this:

    string responseContent;
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
    request.Method = "GET";

    HttpWebResponse response = (HttpWebResponse)request.GetResponse();

    Stream responseStream = response.GetResponseStream();
    using (StreamReader sr = new StreamReader(responseStream))
        responseContent = sr.ReadToEnd();

    return responseContent;

But this code was very slow and it took several seconds to get the response.
One reason for that is that if you don’t use a proxy or just don’t set the proxy property of the WebRequest, it tries to auto-detect and configure a proxy what causes a significant delay.
So just adding

    request.Proxy = null;

before the GetResponse() call will fix that problem.

Remark/Update: To be more correct, you should set “request.Proxy = GlobalProxySelection.GetEmptyWebProxy();” instead of just null. (MSDN: HttpWebRequest.Proxy property)

Another point is that you should always close the WebResponse after processing its contents. That might also speed up your requests. I prefer to use “using” statements to do that. It will get a bit nested sometimes but this way you just can’t forget it.
So here’s the final code for a simple “GET” request:

public string MakeWebRequest(string url)
{
    try
    {
        string responseContent;
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
        request.Method = "GET";
        request.Proxy = GlobalProxySelection.GetEmptyWebProxy(); // null;

        using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
        {
            using (Stream responseStream = response.GetResponseStream())
            {
                using (StreamReader sr = new StreamReader(responseStream))
                    responseContent = sr.ReadToEnd();
            }
        }

        return responseContent;
    }
    catch (Exception ex)
    {
        // Error handling
        return ex.Message;
    }
}

Extending the code for a “POST” request:

To make a “POST” request we have to add the following:

public string MakeWebRequest(string url, string postData)
{
    try
    {
        string responseContent;
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
        // Set Method to "POST"
        request.Method = "POST";
        // Convert "POST" data to a byte array
        byte[] byteArray = Encoding.UTF8.GetBytes(postData);
        // Set the content type of the WebRequest
        request.ContentType = "application/x-www-form-urlencoded";
        // Set the content length
        request.ContentLength = byteArray.Length;
        // Get the request stream
        using (Stream requestStream = request.GetRequestStream())
        {
            // Write the "POST" data to the stream
            requestStream.Write(byteArray, 0, byteArray.Length);
        }
        // Don't forget to set the proxy
        request.Proxy = GlobalProxySelection.GetEmptyWebProxy(); // null;

        using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
        {
            using (Stream responseStream = response.GetResponseStream())
            {
                using (StreamReader sr = new StreamReader(responseStream))
                    responseContent = sr.ReadToEnd();
            }
        }

        return responseContent;
    }
    catch (Exception ex)
    {
        // Error handling
        return ex.Message;
    }
}
public string MakeWebRequest(string url)
{
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = “GET”;
request.Proxy = null;

using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
Stream responseStream = response.GetResponseStream();
using (StreamReader sr = new StreamReader(responseStream))
{
string responseContent = sr.ReadToEnd();
return responseContent;
}
}
}
catch (Exception ex)
{
return ex.Message;
}
}

Git, Git, Git

Today i decided to try out a new version control system: Git.

Git becomes more and more popular these days because of its speed, its decentralized structure and several other new approaches to version management. So I decided to take a first look at it. After reading through some articles about Git and its integration for Windows I created an account at Github and downloaded GitExtensions which includes the msysgit, a Git client for Windows. It also delivers a shell extension and a Visual Studio add-in. After I installed it I sadly discovered that there wasn’t a new entry in the context menu and in Visual Studio i also couldn’t recognize a new tab or something. Ok, so I restarted my PC. After that a Git tab appeared in Visual Studio but the shell extension still wasn’t there. Besides that the GUI was very slow. Every dialog loaded several seconds until it was usable. Not a good start with Git. But perhaps there are still some issues with Win7 x64. I uninstalled it from my Desktop PC but gave it a second chance and installed it on my laptop, which runs 32bit WinXP. And it worked. The shell extension, the VS add-in and without restart.

Ok, fine. But for my desktop that’s not much of use. Another interface to Git is TortoiseGit. I usually use TortoiseSVN + AnkhSVN for source control, so I had high expectations in this one. The first impression was quite good as it looked very familiar. But on second sight it seemed not so polished as I expected. The icon overlays didn’t work well and i couldn’t find the “git add” option to put changes to the staging area. Perhaps the unreliable behaviour is again due to my system, but in the end it didn’t convince me and I dropped it.

Now I’m just going with the normal tools from msysgit: Git Bash and Git GUI which are ok and quite uncomplicated to use. And the best of all, they work. I also found some nice introductions that illustrate the general use of msysgit and the setup of a repository at Github e.g. here or here.

I didn’t do that much operations with Git until now and it’s quite early to form a final opinion about it, but from what I saw it has much potential to establish itself also in the windows world provided that it will get a nice and friendly user interface and integration to VS. Besides the fact, that they didn’t work as intended on my machine, GitExtensions and TortoiseGit are doing good steps in that direction.

I really like the staging area or the uncomplicated setup of a new repository and creation of branches and I definitely will use it more often in the future.

Win7 GodMode?

As you might have noticed, there were many posts and comments on this topic around the internet lately. It’s a nice feature imo and worth a mention in here.

First of all, what is this ominous GodMode and how can I enable it?

The “GodMode” allows you to have a complete list of all Control Panel options in one folder. You can simply achieve this by creating a new folder and append “.{ED7BA470-8E54-465E-825C-99712043E01C}” to its name (don’t forget the dot). The folder name is irrelevant, you can name it whatever you like. Or you just paste “shell:::{ED7BA470-8E54-465E-825C-99712043E01C}” into the explorer address bar and press enter. You can then just drag the icon and put a shortcut whereever you like.

But this is not a so secret feature as you might think. It is documented in the MSDN along with many other GUIDs you can use the same way. You can also search google for “CLSID list” or similar things and you will find many other useful GUIDs. I personally linked my explorer shortcut in the Win7 taskbar to the “My Computer” folder which i think is much more useful than the default location. To do this you have to navigate to the “Windows Explorer” in the Start Menu (under Accessories) and open the properties. Then change the Target to: “%windir%\explorer.exe /root,::{20D04FE0-3AEA-1069-A2D8-08002B30309D}”.

Vista x64 users shouldn’t create a folder using the “GodMode” GUID, as the explorer will most likely hang-up. I don’t know if the other GUIDs will work or not. If you tried it anyhow you have to remove the folder by starting the Task Manger and open the command line by clicking on “File -> New Task (Run…)” and inserting “rd <folderpath>”.

If you just want a complete list of all Control Panel options, but don’t want to handle around with the GUIDs you can also simply open the Control Panel and type a small “a” into the search bar. Et voilà, same effect, less effort.

Howdy!

So, this is my first Post in my first Blog.

This blog shall serve as my private journal in the first place. It will focus on programming in the broadest sense. And if some people out there can make use of my entries, all the better.

I really had a hard time deciding whether i shall blog in english or in german. And I’m still not quite sure about it. But as you might have noticed I started out writing in english, so let’s just see what happens. It will also not hurt my english skills 😉

There are so many options and preferences you can set in the admin panel and that i don’t oversee at the moment. So the appearence of the blog might change by and by.

I think thats it for the moment. Gotta shovel snow now.

%d bloggers like this: