Posts Tagged Microsoft Visual Studio

C# Short Takes – 1 – XML Comments syntax for the cref attribute to a Generic Type Method


Introduction

For the last couple of blog posts I have been using the XML Documentation feature of C# and Sandcastle to generate chm help files. This has resulted in help for methods I have been developing being available in many parts of the Visual Studio environment. Enabling Intelescensecontext sensitive help have proved to quite useful, and is a good thing to include with the source code I have been posting on the blog.

Things have been going quite well with this approach, until I ran into a problem with the <see/> tag and the cref attribute. This tag generates a hyperlink within the output files, after Sandcastle has processed them. These generated hyperlinks to methods in the documentation were a feature I wanted to enable in a couple of places within the generated documentation.

The Problem

The situation which caused me a headache was trying to make pair of <see/> tag elements in the XML Documentation which referenced each of a pair of generic methods. The method signatures were:

public static IEnumerable<TSource> ToIEnumerable(TSource val)
public static IEnumerable<TSource> ToIEnumerable(TSource val1, TSource val2)

The Solution

After trying a number of things and searching on the net, I discovered the following on stackoverflowC#, XML-Doc: Refering to a generic type of a generic type in C# XML documentation?. The last answer in to the question is the one that gave me the way to solve the problem.

Simply, what is required is the xml escaping of the <>I n the function name. For a full (I would expect) list of the xml escape sequences see: List of XML and HTML character entity references.

The resulting references in the <see/> tag end up as:

        /// <see cref="ToIEnumerable&lt;TSource&gt;(TSource)"/> 
 /// <see cref="ToIEnumerable&lt;TSource&gt;(TSource, TSource)"/> 

Reasoning Why It Works

This makes a degree of logical sense when you consider the resulting context of this attribute. The C# compiler translates the XML Documentation into a XML file. Within an XML file an attribute, or element, which contains a < or > character needs to have those characters translated into XML escape equivalents. Thus, the target of the link will be in an XML escaped form, so also the reference to the target should comply with the same XML escape sequences.

A Visual Studio Handy Hint

There is a built-in paste function, Edit.PasteAlterernate. The following blog post ‘What is Paste Alternate?’ describes what this function does. If you use this to paste a function signature from a C# file into a html file, you get the prototype with xml escapes included, plus a bunch of html. Using this paste variant may prove useful when you need a quick way of generating xml escapes .

In my version of Visual Studio, this function was unbound to a keystroke combination. Yu can use the Tools -> Options menu items to get up the dialogue box that allows setting the keystroke combination. The keystroke combinations are set in the Environment -> Keyboard section of this dialogue box.

Conclusions

I trust that reading to here, you have found blog post useful, or that it has helped solves you XML Documentation problems.

, , , , , , , , ,

5 Comments

TPL Dataflow–First Tests


Introduction

Over the last couple of weeks, i attended Tech Ed Australia. The sessions by Joseph Albahari on what is coming C# 4 and available in the Async CTP now, has finally spurred me to go exploring.

What I wanted to achieve

I set out to start creating some simple examples of data flow networks, which employ the asynchronous elements of the framework. The key elements of my testing, and explorations where:

  • As is my want, I always do my exploring with console applications, rather than more elaborate UI’s. This put me in bit of a bind as most of the examples I would locate were things with Winforms or WPF / ZAML  UI’s. I’d rather not spend time mucking about with the UI.
  • Having a UI thread, makes some of the async examples far simpler, as there is a tread which wants to keep running until the application is closed. This makes doing thing with async CTP data flow much simpler.
  • Most of the examples used external things like web pages to get the async happening. I wanted to just have a data driven, from within the program, approach.

Where Did I Get

Example 1

private static void Test1()
{
    Action<int> fred = (i) =>
    {
        int j = i + 1;
        Debug.WriteLine(j);
    };
    var a = new ActionBlock<int>(fred);
    a.Post(1);
    a.Post(2);
    a.Post(3);
    Debug.WriteLine("Test 1 Done");
}

This seems to work, but there is a hidden fault in the code (more on  that later).

On the up side, getting a simple ActionBlock and posting to it may seem trivial, but proves things are installed correctly

Example 2

private static void Test3()
{
    var actor = new ActionBlock<int>((i) =>
    {
        Debug.WriteLine(i);
    });
    var trans1 = new TransformBlock<int, int>((i) =>
    {
        return i * 2;
    }
    );
    trans1.LinkTo(actor);
    for (int i = 1; i < 10; i++)
    {
        trans1.Post(i);
    }
    Debug.WriteLine("Done Test 3");
}

This is an example of wiring two async processing blocks together (the LinkTo in the code).  Again, trivial but does prove the point that I am on the right track. Again, there is an error in here, which does not become obvious in a trivial example.

Example 3

private static void Test4()
{
    var actor = new ActionBlock<int>((i) =>
    {
        Debug.WriteLine(
            string.Format("Action {0}", i));
    });
    var trans1 = new TransformBlock<int, int>((i) =>
    {
        int res = i * 2;
        Debug.WriteLine(
            String.Format("Transform of {0} to {1} Done", i, res));
        return res;
    }
    );
    trans1.LinkTo(actor);
    for (int i = 1; i < 10; i++)
    {
        if (trans1.Post(i))
            Debug.WriteLine(
                String.Format("Post of {0} Succeeded", i));
        else Debug.WriteLine(
                String.Format("Post of {0} Not Accepted", i));
    }
    Debug.WriteLine("Done Test 4");
}

This is very much like Example 2, but provides nicer output. The benefit of the output is the you can see that things are happening asynchronously.

Example 4

private static BroadcastBlock<int> Test5()
{
    int factor1 = 2;
    var trans1 = new TransformBlock<int, int>((i) =>
    {
        int res = i * factor1;
        Debug.WriteLine(
            String.Format("1 Transform of {0} to {1} Done", i, res));
        return res;
    }
    );
    int factor2 = 3;
    var trans2 = new TransformBlock<int, int>((i) =>
    {
        int res = i * factor2;
        Debug.WriteLine(
            String.Format("2 Transform of {0} to {1} Done", i, res));
        return res;
    }
    );
    var actor1 = new ActionBlock<int>((i) =>
    {
        Debug.WriteLine(
            string.Format("1 Action {0}", i));
    });
    var actor2 = new ActionBlock<int>((i) =>
    {
        Debug.WriteLine(
            string.Format("2 Action {0}", i));
    });
    trans1.LinkTo(actor1);
    trans2.LinkTo(actor2);
    BroadcastBlock<int> bcBlock =
        new BroadcastBlock<int>((i) =>
        {
            return i;
        });
    bcBlock.LinkTo(trans1);
    bcBlock.LinkTo(trans2);
    return bcBlock;
}

This is the part which builds the data flow network, which is getting more elaborate. There are five elements which are linked together to provide a more interesting network.

private static void Test5_Main()
{
    BroadcastBlock<int> bcBlock = Test5();
    for (int i = 0; i <= 10; i++)
    {
        if (bcBlock.Post(i))
            Debug.WriteLine(
                String.Format("Post of {0} Succeeded", i));
        else Debug.WriteLine(
                String.Format("Post of {0} Not Accepted", i));
    }
    bcBlock.Complete();
    while (bcBlock.Completion.IsCompleted == false)
    {
        Debug.WriteLine("Thread Sleeping");
        Thread.Sleep(1000);
    }
    Debug.WriteLine("Done");
    return;
}

This is the main for this example. There are a couple of key point, and a solution to the problem (or bug) I mentioned above. The bug was that sometimes the networks were not getting enough time to complete before the main thread was exiting. There result was that sometimes the output would be incomplete.  There key elements are:

  • Posting the data into the network.
  • The Broadcast block sends that data into both of the two TransformBlock and ActionBlock chains.
  • The BroadcastBlock Complete, tells the BroadcastBlock that there will be no more inputs, and when you are empty, to mark yourself “Completed”.
  • The while loop keeps the main thread running, while the data passes through the network.

Conclusions

  • There are simple to the point of trivial examples, but a place to start.
  • The Async CTP is something which I will continue to play with. The construction of these examples has been an interesting learning journey.
  • I have some ideas for more elaborate networks, and simulations of networks of relationships.
  • Future posts could start to explore more of what is available from the Async Data Flow CPT.

, , , , ,

1 Comment

Where are the Visual Studio Parallel Debug Tools?


Introduction

If you are just venturing into doing things in parallel with Visual Studio this one will be of interest you.

Being someone who is starting out using Visual Studio to develop parallel tasks, I’ve watched some demonstration of the support for parallel tasks in Visual Studio. That was fine, but when I came to get those nice windows up for my project I could not find where they were hidden.

The Parallel Task and Parallel Stack Windowsclip_image002

The only way I have found to get these windows displayed is as follows:

  1. Put some breakpoints into the code which has parallel activity. I put these break points into the “bits” of code I know are off on parallel tasks.
  2. Start debugging the program.
  3. Go to the Debug Tools Tool Bar, and select the “Breakpoints” icon. This then presents the dropdown menu with the parallel tool windows.
  4. There you can see there are keyboard short cuts to open the windows. This is fine if you can get the menu up and read the shortcuts, but I could never find the option to get the menu up. Why, these items only appear when the program is in “debug mode”.

 

Conclusions

  • This is another one of those, “easy when you know how” type of things. It is not entirely obvious when you start looking for the Parallel tools where to find them.
  • There are probably (undoubtable) other ways to get these windows up, but this is the one which I have found.

, , , , , , , ,

1 Comment

%d bloggers like this: