• Shortcuts : 'n' next unread feed - 'p' previous unread feed • Styles : 1 2

» Publishers, Monetize your RSS feeds with FeedShow:  More infos  (Show/Hide Ads)


Date: Monday, 17 Sep 2012 16:02

Following last Wednesday’s official launch of Visual Studio 2012, we’re excited to announce that the Roslyn September 2012 CTP is now available for download and provides support for VS 2012 RTM. Please note that Visual Studio 2010 is no longer supported by this CTP.

We’ve been hard at work since the first public release of Roslyn adding support for new language features and improving our APIs. In addition, we’ve also updated our NuGet packages to match the September 2012 CTP.

As always, your feedback is critical! Please get involved in the discussion on the Roslyn forum, file bugs on Connect, or just give us a shout-out on Twitter @ #RoslynCTP!

 

Enjoy!

Dustin Campbell

 

About the Author

Dustin Campbell is a Program Manager responsible for the C# and VB language experiences on the Roslyn project.

Author: "CSharpFAQ" Tags: "IDE, C#, C# compiler, roslyn"
Send by mail Print  Save  Delicious 
Date: Tuesday, 26 Jun 2012 16:00

by Alan Berman

The Async feature in Visual Studio 2012 RC makes it easy to invoke asynchronous methods.

If you mark a method with or async modifier, you can use the await operator in the method. When control reaches an await expression in the async method, control returns to the caller, and progress in the method is suspended until the awaited task completes. When the task is complete, execution can resume in the method.

Using asynchronous methods instead of synchronous methods can provide benefits.  Asynchrony makes UI applications more responsive because the UI thread that launches that operation can perform other work.  Asynchrony also improves the scalability of server-based application by reducing the need for threads.

This blog provides a simple async example and describes what occurs when it runs. It also provides an example of exception handling for a call to an async method.


Running the Examples

To run the examples in this blog, you can do the following:

  1. Install Visual Studio 2012 RC, which can be accessed from Visual Studio Asynchronous Programming.
  2. Create WPF Application or Windows Forms Application.
  3. In your project, add a reference to System.Net.Http.  This allows you to use the HttpClient class in the first example,
  4. Add a Button to the application.  Modify the Button_Click event handler to add the async modifier.  The Button_Click event handlers in the examples are from a WPF Application, however they can be modified for a Windows Form Application.
  5. Include the following using statements.

    using System.Diagnostics;
    using System.Net.Http;
    using System.Threading.Tasks;

 

Example of async and await

The following example illustrates use of the async modifier and the await operator.  An explanation is provided below.  Note that startButton_Click is marked with the async modifier


    private async void startButton_Click(object sender, RoutedEventArgs e)
    {
        Task<string> getWebPageTask = GetWebPageAsync("
http://msdn.microsoft.com");

        Debug.WriteLine("In startButton_Click before await");
        string webText = await getWebPageTask;
        Debug.WriteLine("Characters received: " + webText.Length.ToString());
    }

    private async Task<string> GetWebPageAsync(string url)
    {
        // Start an async task.
        Task<string> getStringTask = (new HttpClient()).GetStringAsync(url);

        // Await the task. This is what happens:
        // 1. Execution immediately returns to the calling method, returning a
        //    different task from the task created in the previous statement.
        //    Execution in this method is suspended.
        // 2. When the task created in the previous statement completes, the
        //    result from the GetStringAsync method is produced by the Await
        //    statement, and execution continues within this method.
        Debug.WriteLine("In GetWebPageAsync before await");
        string webText = await getStringTask;
        Debug.WriteLine("In GetWebPageAsync after await");

        return webText;
    }

    // Output:
    //   In GetWebPageAsync before await
    //   In startButton_Click before await
    //   In GetWebPageAsync after await
    //   Characters received: 44306


Control Flow in Example

In the above example, the startButton_Click method calls the GetWebPageAsync method.  In the GetWebPageAsync method, the following occurs:

  1. The GetWebPageAsync method calls the GetStringAsync method, which returns a task.
  2. The “await getStringTask” expression causes the GetWebPageAsync method to immediately exit and return a different task.  Execution in the GetWebPageAsync method is suspended.
  3. When the awaited task (getStringTask) completes at a later time, processing resumes after the await statement in the GetWebPageAsync method.

The startButton_Click method also contains an await expression, which is “await getWebPageTask”.  Because GetWebPageAsync is an async method, the task for the call to GetWebPageAsync needs to be awaited.  startButton_Click needs to be defined with the async modifier because it has an await expression.


Return Types in Example

In the above example, the GetWebPageAsync method has a return statement that returns a string.  Therefore, the method declaration of GetWebPageAsync has a return type of Task<string>.  Because the return type is Task<string>, the evaluation of the await expression in startButton_Click produces a string, as the following statement demonstrates:  string webText = await getWebPageTask; .

Similarly, the GetWebPageAsync method calls the GetStringAsync method, which is defined with a return type of Task<string>. The call to GetStringAsync returns a Task<string> and the evaluation of the await expression produces a string.

The startButton_Click method has a return type of void.

Note:  An async method can have a return type of Task<TResult>, Task, or void.   The void return type is used primarily to define event handlers, where a void return type is required. An async method that returns void can't be awaited, and the caller of a void-returning method can't catch exceptions that are thrown by the method.


Simplified Code

In the above example, the GetWebPageAsync method includes the following two statements:

    Task<string> getStringTask = (new HttpClient()).GetStringAsync(url);
    string webText = await getStringTask;


The above two statements can be condensed into one statement, as follows:

    string webText = await (new HttpClient()).GetStringAsync(url);


The condensed statement also returns a task and awaits the task, however the task is not stored in a variable. While the condensed statement is more concise, the uncondensed code facilitates a greater understanding of the control flow of your code, and of the associated tasks.

 

Exception Handling

The following example illustrates exception handling for an async method. To catch an exception that applies to an async task, the await expression is in a try block, and the exception is caught in a catch block.

Uncomment the “throw new Exception” line in the example to demonstrate exception handling. The exception is caught in the catch block, and the task's IsFaulted property is set to true, and the task's Exception.InnerException property is set to the exception.

Uncomment the “throw new OperationCancelledException” line to demonstrate what happens when you cancel an asynchronous process. The exception is caught in the catch block and the task's IsCanceled property is set to true. Under some conditions that don't apply to this example, IsFaulted is set to true and IsCanceled is set to false.

    private async void testExceptionButton_Click(object sender, RoutedEventArgs e)
    { 
        Task<string> theTask = DelayAsync();

        try 
        { 
            string result = await theTask; 
            Debug.WriteLine("Result: " + result); 
        } 
        catch (Exception ex) 
        { 
            Debug.WriteLine("Exception Message: " + ex.Message); 
        } 
        Debug.WriteLine("Task IsCanceled: " + theTask.IsCanceled); 
        Debug.WriteLine("Task IsFaulted:  " + theTask.IsFaulted); 
        if (theTask.Exception != null) 
        { 
            Debug.WriteLine("Task Exception Message: " 
                + theTask.Exception.Message); 
            Debug.WriteLine("Task Inner Exception Message: " 
                + theTask.Exception.InnerException.Message); 
        } 
    }

    private async Task<string> DelayAsync()
    {
        await Task.Delay(100);

        // Uncomment each of the following lines to
        // demonstrate exception handling.

        //throw new OperationCanceledException("canceled");
        //throw new Exception("Something happened.");
        return "Done";
    }

    // Output when no exception is thrown in the awaited method:
    //   Result: Done
    //   Task IsCanceled: False
    //   Task IsFaulted:  False

    // Output when an Exception is thrown in the awaited method:
    //   Exception Message: Something happened.
    //   Task IsCanceled: False
    //   Task IsFaulted:  True
    //   Task Exception Message: One or more errors occurred.
    //   Task Inner Exception Message: Something happened.

    // Output when a OperationCanceledException or TaskCanceledException
    // is thrown in the awaited method:
    //   Exception Message: canceled
    //   Task IsCanceled: True
    //   Task IsFaulted:  False

 

See Also

Resources

Author: "CSharpFAQ" Tags: "async, await, asynchronous programming, ..."
Send by mail Print  Save  Delicious 
Date: Tuesday, 05 Jun 2012 19:54

Today, we're excited to announce that the Roslyn June 2012 CTP is now available for download!

Since the first public release of Roslyn, we’ve been hard at work implementing new language features, addressing top customer feedback from the Oct CTP, iterating on our API design and improving performance across our IDE and compiler scenarios.  With the recent release of Visual Studio 2012 RC, we have updated the Roslyn CTP to work with Visual Studio 2012 RC, in addition to Visual Studio 2010 SP1.  There’s never been a better time to grab the VS 2012 RC and the Roslyn CTP and start exploring with the new Roslyn Interactive window!

You can find an in-depth look at what’s new in the Roslyn June 2012 CTP on Jason Zander’s blog and the Visual Studio blog.  The CTP ships with a number of documents that provide an excellent way to get started – start with the overview document, and then move on to the walkthroughs.  We also encourage you to check out our previous series on how to use the Roslyn APIs – the syntax visualizer is an invaluable tool, the Syntax API, the Symbol API, the Scripting API, and how to write a code action

Feedback is a critical part of our design process!  Because it’s early in the project, we’re most interested in feedback around the API and understanding what scenarios you’d like to accomplish. Please get involved in the discussion about Roslyn on our forums. You can also file bugs on our Connect site. Some of the team members are also on Twitter, and will be keeping an eye on the #RoslynCTP hashtag.

 

Happy Coding!

Karen Ng

 

About the Author

Karen Ng is the Lead Program Manager responsible for the compilers, IDEs, and Languages for C#, Visual Basic, and F# at Microsoft.  Karen works on both the Visual Studio 2012 release and the Roslyn project.

Author: "CSharpFAQ" Tags: "IDE, C#, C# compiler, roslyn"
Send by mail Print  Save  Delicious 
Date: Thursday, 26 Apr 2012 20:39

If you’ve held off on trying Visual Studio 11 Beta because your .NET 4 or Silverlight 5 app uses the Async CTP, your wait is over!  Today we’ve published the Async Targeting Pack for Visual Studio 11, a NuGet package that lets your Visual Studio 11 projects target .NET 4 and Silverlight 5 while taking advantage of C#’s new await keyword.  While Visual Studio 11 provides built-in support for await in projects that target .NET 4.5 or .NET for Metro style apps, this targeting pack provides the API support to expand the set of target platforms to include .NET 4 and Silverlight 5 as well.

Check out our release notes for more details on how to install NuGet and add the package reference in Visual Studio 11 Beta.

Happy testing!

Alex Turner
Program Manager, VB/C# Compilers

Author: "CSharpFAQ" Tags: ".NET Framework 4, async, await, asynchro..."
Send by mail Print  Save  Delicious 
Date: Wednesday, 29 Feb 2012 14:55

As you may have seen in Jason’s blog, Visual Studio 11 Beta is available for download today, including the Beta version of C# 5.0!  If you’ve tried out the Visual Studio 11 Developer Preview, you already know that this is an exciting release, with two huge new features for C# developers: async methods and support for creating Windows 8 Metro style apps.  However, with Beta comes even more goodness, with support for caller info attributes, as well as a host of async perf improvements and async unit-testing support.

The best way to see what’s new in Visual Studio 11 is to dive in and try it yourself.  However, if you’re curious to know what you’re getting, read on!

Async methods (the await keyword)

As you migrate your desktop applications to mobile phones and tablets, you’re increasingly faced with the realities of network latency, especially given a reliance on cloud services running in distant datacenters.  At the same time, your users expect far more responsiveness from these applications, with the bar set by smooth touch UIs that never drop a frame.

The way out of this conundrum up to now has been asynchronous programming and the use of callbacks.  However, while callbacks can work for very simple methods, you quickly fall into the pit of despair for code that’s of any reasonable length or complexity, giving up the core control flow constructs you’ve trusted for years – chained callback methods and for loops don’t mix!

There has to be a way out of this mess, and there is – async methods in C# 5.0, powered by the await keyword:

public async Task<int?> SumPageSizesAsync(IList<Uri> uris) {
    try {
        int total = 0;
        var client = new HttpClient();
        client.MaxResponseContentBufferSize = 10000000;
        foreach (var uri in uris) {
            statusText.Text = string.Format("Found {0} bytes ...", total);
            var data = await client.GetByteArrayAsync(uri);
            total += data.Length;
        }
        statusText.Text = string.Format("Found {0} bytes total", total);
        return total;
    }
    catch (Exception) {
        statusText.Text = "Error!";
        return null;
    }
}

By marking your method with the async keyword, the C# compiler transforms it into a resumable async method that can pause execution whenever it sees the await keyword by returning control to the caller.

  • If this is a client app, control returns to your caller at each await, and then to its caller, and so on, until you’ve freed up the UI thread, which keeps your app responsive.
     
  • If you’re writing a server, returning to the caller frees up the thread handling the current request, ensuring that thread is available to process other requests and increasing your scalability.

In either case, once the operation you’re awaiting completes, your method wakes up, resuming execution right where it left off, even if you were within a foreach loop or a try-catch block.  When execution is paused, you can even hit F10 to Step Over at the await, with the debugger returning you to the following line after the awaited operation completes.

This is just a brief peek at Async – if you’ve yet to try it, be sure to check out the Asynchronous Programming Developer Center for samples, videos and more to get started.  However, if you have been using Async for a while now through our previous preview releases, you’ll be excited to see what’s new in Beta!

Since the Developer Preview, we’ve done work to further improve the perf of async methods, reducing allocations to ensure you can feel comfortable using async methods throughout your application, wherever you need them.  However, such comfort also requires that you can trust your async methods to continue working as expected as you continue to make changes elsewhere in your app.  To this end, MSTest and xUnit.net now support async methods directly, ensuring that the test runner waits for the async method to fully complete:

[TestMethod]
public async Task Test1() {
    var x = await Engine.GetSevenAsync();
    Assert.AreEqual(x, 6);
}

[Xunit.Fact]
public async Task Test2() {
    var y = await Engine.GetSevenAsync();
    Assert.AreEqual(x, 6);
}

Caller Info Attributes

One language feature that’s making its debut in Visual Studio 11 Beta is caller info attributes.  These attributes let a method accept implicit optional parameters intended to receive a line number, a file path or a member name.  Then, at the call site, the compiler will know to automatically fill in those argument values, based on the exact location where that method was called.

One great use for caller info attributes is for logging methods.  The code below defines a LogMessage method that accepts 4 parameters to output a structured log message.  However, when we call LogMessage within ProcessItem, we only need to specify one argument, message – the compiler will do the work for us to pass in the name of the method calling LogMessage, along with the file name and line number of that call site.  Even better, if ProcessItem moves around in the file, changes files, or is renamed, the log message will be updated automatically.

public void LogMessage(string message = "",
                       [CallerMemberName] string member = "",
                       [CallerFilePath] string file = "",
                       [CallerLineNumber] int line = 0)
{
    var s = String.Format("{1} ({2}:{3}) - {0}", message, member, file, line);
    Debug.WriteLine(s);
}

public void ProcessItem(int index) {
    LogMessage(String.Format("Processing item {0}", index));

   
DoSomeWork();
}

Another benefit is when you’re implementing INotifyPropertyChanged.  Today, it’s common to write a helper method that invokes the PropertyChanged event, to which you pass the name of the property being set.  However, you must then pass that property name as a string argument within each property setter.  This adds risk when refactoring inside such classes – if you use VS to change the name of the property and all its references, you’ll have to manually update that string.

With caller info attributes, you can just call your NotifyPropertyChanged helper as below, without arguments.  The compiler will pass in the name of the property for you, which will always be up to date, even if the property is renamed:

public class Widget : INotifyPropertyChanged
{
    private string statusText;
    public string StatusText
    {
        get { return statusText; }
        set { statusText = value; NotifyPropertyChanged(); }
    }

    public void NotifyPropertyChanged([CallerMemberName] string property = null)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(property));
        }
    }
 
   public event PropertyChangedEventHandler PropertyChanged;
}

Call to Action

If you’re excited to try out Metro style app development, async methods, caller info attributes and all the other performance and productivity improvements in Visual Studio 11 Beta, there’s a set of great resources available to explore:

  1. Get the bits!  The first step is to download Visual Studio 11 Beta – this page also has links to download Team Foundation Server 11 Beta and .NET Framework 4.5 Beta.  You can install Visual Studio 11 Beta on Windows 7 to get up and running quickly, or set it up on top of the Windows 8 Consumer Preview to start writing Metro style apps.
     
  2. Learn and explore!  Check out Jason's blog post on Visual Studio 11 Beta and .NET Framework 4.5 Beta, and then dig deeper into what’s new in Visual Studio 11 Beta.  To explore what’s new in Windows 8, first read the Building Windows 8 blog post announcing the Windows 8 Consumer Preview, and then browse the new Windows 8 app developer blog.
     
  3. Share your feedback!  As you build apps in Visual Studio 11 Beta, let us know what you think!  Discuss what’s working well and what could be better on the Visual Studio and Windows 8 forums, and be sure to file any bugs you find through the Visual Studio, LightSwitch, and Blend Connect sites.  Also, vote on the features you’d like to see in Visual Studio moving forward on our UserVoice site.

Most importantly, have fun with the Beta and build some awesome apps!

Alex Turner
Program Manager, VB/C# Compilers

Author: "CSharpFAQ" Tags: "async, await, asynchronous programming, ..."
Send by mail Print  Save  Delicious 
Date: Monday, 06 Feb 2012 16:38

 By Brian Rasmussen

The Roslyn Services API makes it easy to implement extensions that detect and fix code issues directly in Visual Studio. The Roslyn Services API is available as part of the Roslyn CTP.

In this post we implement a Visual Studio extension that identifies calls to the extension method Count() on Enumerable, where the result is compared to greater than zero, e.g. someSequence.Count() > 0. The problem, with that code construct, is that Count() may have to enumerate the entire sequence to evaluate the result. A much better approach in this case is to call Enumerable.Any() instead.

To address this we implement a CodeIssueProvider, which detects the problem and a CodeAction, which replaces the condition with a call to Enumerable.Any() as appropriate. E.g. our code action will change someSequence.Count() > 0 to someSequence.Any().

There are a couple additional scenarios, we want to handle as well: First of all, the expression could be reversed and written like 0 < someSequence.Count(). The other special case is that the comparison could be >= 1 instead of > 0, which is essentially the same comparison as before. We want the extension to be able to handle both of these cases.

Obviously we do not want to change calls to methods called Count() unless they bind to the IEnumerable<T> extension method defined on Enumerable.

Getting Started

The Roslyn CTP ships with a number of templates designed to make it easy to get started using the Roslyn APIs. To get started we create a new project and select Code Issue from the Roslyn templates under the Visual C# section. Let’s call the project ReplaceCountWithAny.


The template generates a small, working code issue provider that will highlight words with the letter “a”. To see the sample in action let’s build and run the project created by the template. This launches a new instance of Visual Studio with the extension enabled. From the newly launched Visual Studio we create a console application and notice how the namespace and class keywords and so on are underlined by our extension.

While the sample may not be very useful as an extension to Visual Studio, it neatly sets up everything we need to get started implementing our own extension. All we have to do is replace the contents of the generated GetIssues method. Notice that there are three overloads for GetIssues. We’ll implement the overload that takes a CommonSyntaxNode as input. The remaining two overloads can be left as they are in this case.

The generated CodeIssueProvider class implements ICodeIssueProvider and is decorated with the ExportSyntaxNodeCodeIssueProvider attribute. This allows Visual Studio to import this type as an extension, which will handle the contract established by the ICodeIssueProvider interface.

Implementing GetIssues

Our GetIssues method will be invoked for every syntax node, so the first thing we need to do is filter out all the nodes we don’t want to handle. Since we are looking for expressions like someSequence.Count() > 0, we’re only interested in nodes of the type BinaryExpressionSyntax. We can instruct Visual Studio to only invoke our provider for nodes of specific type(s) by providing a list of types through the ExportSyntaxNodeCodeIssueProvider attribute. Let’s update the attribute as follows:

[ExportSyntaxNodeCodeIssueProvider("ReplaceCountWithAny"
LanguageNames.CSharp, typeof(BinaryExpressionSyntax))]
class CodeIssueProvider : ICodeIssueProvider ...

This allows us to safely cast the provided CommonSyntaxNode to BinaryExpressionSyntax in GetIssues.

To identify the cases we want to handle we have to figure out if one part of the expression is a call to Enumerable.Count() and the other part is a relevant comparison. We’ll abstract those checks into a couple helper methods, so with that our implementation of GetIssues looks as follows.

public IEnumerable<CodeIssue> GetIssues(IDocument document, 
    CommonSyntaxNode node, CancellationToken cancellationToken)
{
    var binaryExpression = (BinaryExpressionSyntax)node;
    var left = binaryExpression.Left;
    var right = binaryExpression.Right;
    var kind = binaryExpression.Kind;
    if (IsCallToEnumerableCount(document, left, cancellationToken) && 
        IsRelevantRightSideComparison(document, right, kind, cancellationToken) ||
        IsCallToEnumerableCount(document, right, cancellationToken) && 
        IsRelevantLeftSideComparison(document, left, kind, cancellationToken))
    {
        yield return new CodeIssue(CodeIssue.Severity.Info, binaryExpression.Span,
            string.Format("Change {0} to use Any() instead of Count() to avoid " +
                          "possible enumeration of entire sequence.", 
                          binaryExpression));
    }
}
 

The instance of CodeIssue we return specifies a severity level, which can be Error, Warning or Info, a span, which is used to highlight the part of the source code the issue applies to, and a text describing the identified issue to the user.

Helper Methods

Let’s turn our attention to the helper methods used in GetIssues. IsCallToEnumerableCount returns true if the part of the expression we’re looking at is in fact a call to Count() on some sequence. Once again we’ll start by filtering the undesired expressions.

First of all the expression must be an invocation. If that’s the case, we’ll get the actual method call from the Expression property of the invocation. So if the expression we’re looking at is someSequence.Count() > 0 we now have the Count() part, but how do we figure out if this binds to the Enumerable type?

To answer questions like that we need to query the semantic model. Fortunately part of the input to GetIssues is an IDocument, which represents a single document in a project and solution. We can get the semantic model via the document and from there we can get the SymbolInfo we need.

With the SymbolInfo present we can check if our call binds to the desired method. Because Count() is an extension method we’ll need to handle it a bit differently. Recall that C# allows extension methods to be called as if they were part of the calling type. The semantic model represents this as a MethodSymbol with a ConstructedFrom property set to the original type. This could possibly be handled slightly better, so look out for changes in the API here.

All that remains is to figure out the declaring type for our constructed extension method. If that matches Enumerable we have found an invocation of Enumerable.Count().

The implementation looks like this: 

private bool IsCallToEnumerableCount(IDocument document, 
    ExpressionSyntax expression, CancellationToken cancellationToken)
{
    var invocation = expression as InvocationExpressionSyntax;
    if (invocation == null)
    {
        return false;
    }
 
    var call = invocation.Expression as MemberAccessExpressionSyntax;
    if (call == null)
    {
        return false;
    }
 
    var semanticModel = document.GetSemanticModel(cancellationToken);
    var methodSymbol = semanticModel.GetSemanticInfo(call, cancellationToken).Symbol 
        as MethodSymbol;
    if (methodSymbol == null || 
        methodSymbol.Name != "Count" || 
        methodSymbol.ConstructedFrom == null)
    {
        return false;
    }
 
    var enumerable = semanticModel.Compilation.GetTypeByMetadataName(
        typeof(Enumerable).FullName);
 
    if (enumerable == null || 
        !methodSymbol.ConstructedFrom.ContainingType.Equals(enumerable))
    {
        return false;
    }
 
    return true;
} 

With that settled the next thing we need to look for is a relevant comparison on the other side of the binary expression and that’s the job of our IsRelevantRightSideComparison and IsRelevantLeftSideComparison helper methods.

Here are the implementations for those:

private bool IsRelevantRightSideComparison(IDocument document, 
    ExpressionSyntax expression, SyntaxKind kind, 
    CancellationToken cancellationToken)
{
    var semanticInfo = document.GetSemanticModel(cancellationToken).
        GetSemanticInfo(expression);
 
    int? value;
    if (!semanticInfo.IsCompileTimeConstant || 
        (value = semanticInfo.ConstantValue as int?) == null)
    {
        return false;
    }
 
    if (kind == SyntaxKind.GreaterThanExpression && value == 0 ||
        kind == SyntaxKind.GreaterThanOrEqualExpression && value == 1)
    {
        return true;
    }
 
    return false;
}
 
private bool IsRelevantLeftSideComparison(IDocument document, 
    ExpressionSyntax expression, SyntaxKind kind, 
    CancellationToken cancellationToken)
{
    var semanticInfo = document.GetSemanticModel(cancellationToken).
        GetSemanticInfo(expression);
 
    int? value;
    if (!semanticInfo.IsCompileTimeConstant ||
        (value = semanticInfo.ConstantValue as int?) == null)
    {
        return false;
    }
 
    if (kind == SyntaxKind.LessThanExpression && value == 0 ||
        kind == SyntaxKind.LessThanOrEqualExpression && value == 1)
    {
        return true;
    }
 
    return false;
}

 They are almost identical, but it is important that we get the both the comparison and the value correct so we don’t highlight something like Count() >= 0.

Testing the CodeIssueProvider

At this point our code issue provider can detect the issues we’re interested in handling. Compile and run the project to launch a new instance of Visual Studio with our extension enabled. Add some code and notice that calls to Enumerable.Count() are correctly underlined while method calls to other methods named Count() are not.

The next step is to provide a code action for our code issue.

CodeAction

To implement a code action we need a type which implements ICodeAction. ICodeAction is a simple interface that defines a description and an icon for the action and a single method called GetEdit, which returns an edit that will transform the current syntax tree. Let’s start by looking at the constructor for our CodeAction class.

public CodeAction(ICodeActionEditFactory editFactory, 
    IDocument document, BinaryExpressionSyntax binaryExpression)
{
    this.editFactory = editFactory;
    this.document = document;
    this.binaryExpression = binaryExpression;
}

An instance of CodeAction will be created for every code issue identified, so for convenience sake we just pass the arguments we need to implement the change to the constructor itself. We need an ICodeActionEditFactory to create a transformation for our newly created syntax tree. As syntax trees are immutable in Roslyn, returning a new tree is the only way we can make any changes. Fortunately, Roslyn will reuse as much of the original tree as possible and thus avoid creating unnecessary nodes.  

Furthermore we need a document to let us access both the syntax tree and the project and solution for our source code and a reference to the syntax node we want to replace.

This brings us to the GetEdit method. This is where we create a transformation, which will replace the identified binary expression node with a newly created invocation node for the call to Any(). The creation of the new node is handled by a small helper method called GetNewNode. Both are listed below.

public ICodeActionEdit GetEdit(CancellationToken cancellationToken)
{
    var syntaxTree = (SyntaxTree)document.GetSyntaxTree(cancellationToken);
    var newExpression = GetNewNode(binaryExpression).
        WithLeadingTrivia(binaryExpression.GetLeadingTrivia()).
        WithTrailingTrivia(binaryExpression.GetTrailingTrivia());
    var newRoot = syntaxTree.Root.ReplaceNode(binaryExpression, newExpression);
 
    return editFactory.CreateTreeTransformEdit(
        document.Project.Solution,
        syntaxTree,
        newRoot,
        cancellationToken: cancellationToken);
}
 
private ExpressionSyntax GetNewNode(BinaryExpressionSyntax node)
{
    var invocation = node.DescendentNodes().
        OfType<InvocationExpressionSyntax>().Single();
    var caller = invocation.DescendentNodes().
        OfType<MemberAccessExpressionSyntax>().Single();
    return invocation.Update(
        caller.Update(caller.Expression, 
        caller.OperatorToken, 
        Syntax.IdentifierName("Any")),
        invocation.ArgumentList);
}

The Roslyn syntax tree maintains full fidelity with the original source code, so each node in the tree may have both leading and trailing trivia representing white space and comments. I.e. we need to preserve the trivia from the original node to maintain comments and layout of the code when we exchange the nodes. We call the WithLeadingTrivia and WithTrailingTrivia extension methods to handle that.

Also, notice that GetNewNode preserves the argument list from Count(), so if the extension method was invoked with a lambda to count specific items in the sequence so will Any().

Wrapping Up

To enable our code action we need to update GetIssues in our CodeIssueProvider to return a CodeAction with each CodeIssue. Each code issue may provide a number of code actions to let the user pick between different resolutions. In this case we will just return a single code action as outlined above.

The updated part of GetIssues looks like this:

yield return new CodeIssue(CodeIssue.Severity.Info, binaryExpression.Span,
    string.Format("Change {0} to use Any() instead of Count() to avoid " +
                  "possible enumeration of entire sequence.", binaryExpression),
    new CodeAction(editFactory, document, binaryExpression));
    

Rebuild and run the project to launch a new instance of Visual Studio with our extension loaded. Notice that the code issue now provides a drop down with the option to invoke our code action to fix the issue.

We have implemented an extension to Visual Studio that will help us improve our code.

About the author

Brian is a Senior SDET at Microsoft working on the C# and VB language services in Roslyn. Before joining Microsoft Brian was a Microsoft MVP for Visual C# for four years. Brian can be found on Twitter (@kodehoved).

Author: "CSharpFAQ" Tags: "C#, Visual Studio, roslyn"
Send by mail Print  Save  Delicious 
Date: Monday, 06 Feb 2012 15:00

by Alan Berman

I'm intrigued by all the interesting industry apps being developed for the Kinect.  I started wondering how easy it is to start programming the Kinect using Visual Studio on a PC.  It is very easy to get started, especially since the Kinect SDK has sample applications with sample code.

Because I had bought a Kinect bundled with my Xbox and not a standalone Kinect, I needed to buy a Kinect Sensor Power Supply, which can be purchased online.  This product has a cable with a USB connector that can be plugged into a PC.

I downloaded the Kinect SDK from the Kinect for Windows download site.  After installation of the Kinect SDK, this appears in Start / All Programs.

When you choose "Kinect SDK Sample Browser", the following Sample Browser window appears.  You can run the samples and download the associated C# projects from the window.


Here's what the Kinect Explorer looks like.

In the above window, the image at the left demonstrates skeletal tracking. The same image also shows Norm Estabrook as seen from the RGB camera.  For the image at the right, depth camera data with the distance from the Kinect is translated into an image with different colors.

You can change settings by clicking the arrow at the lower left.

Here's what the Shape Game looks like.  Norm is trying to change the direction of shapes falling from the sky.  The app also supports vocal commands.

The Kinect Audio Demo looks like this.  It shows the direction of the sound source and recognizes spoken colors.

The Kinect SDK includes the C# code for these sample apps, which will help you start coding.

Another important resource is the phenomenal Getting Started videos at the Kinect for Windows Quickstart Series.  Happy coding!

Author: "CSharpFAQ" Tags: "Visual Studio 2010, C#, Kinect"
Send by mail Print  Save  Delicious 
Date: Tuesday, 31 Jan 2012 00:22

 

There's been a lot of posts on using the Roslyn CTP APIs for syntax trees, semantic binding, and IDE smart editor features. The Roslyn CTP also introduces a set of features for C# we refer to as "Interactive". These features won't be new to VB, but we plan to bring the same feature set to VB. Interactive features comprise three goals:

· Read-eval-print loop (long known as a REPL) -- to support exploring code, learning about APIs, and iterative development

· Keep simple programs simple -- just write some top-level variable declarations, statements, and function declarations, then run the code as a text-based asset without needing a solution, project, class, Main, etc.

· Roslyn Scripting APIs -- to support .NET apps hosting a C# engine to execute snippets or files of code to script the application

This post talks about the Interactive features in the Roslyn CTP, which is only supported for C# right now, but we are working on VB support for a future release.

Interactive code is a set of language and tooling features that enable customers to interactively explore and discover C# and VB readily. You do not have to create a solution, then a project, then a class, then a Main method and finally then get to write the few lines you care about. Users can open a tool window in VS and start typing code snippets to see what they do. You can build up execution context cumulatively by defining variables and functions, executing statement, defining types, and building up data structures. You can also seed the REPL's execution context from a project so that you can explore instantiating types from the project and trying out new snippets of code or develop a new function or integrity check on the data structures used in the project. This sort of development has been a hallmark of dynamic languages for decades and considered to be one of the most productive features related to dynamic languages.

Some getting started walkthroughs:

Executing Code in the Interactive Window

Seeding the Interactive Window from a WPF Project

For a quick example, using View->Other Windows->C# Interactive and starting to type a reference, you get completion:

clip_image002

After finishing the previous input and hitting enter to execute it, if you start to type MessageBox, you get a quick fix for inserting the 'using' and then completion to help with enter a call to Show().

clip_image004

When using the REPL to iteratively develop code, you may start with simple expression or statement snippets of code. You might be just checking how to call a .NET function correctly, or making a change to live code and data structures, then writing a snippet to check whether the change occurred as expected. You might build up helper functions that, for example, either help you recreate execution context for experimenting in another REPL session or help you repeat integrity checks as you experiment with an algorithm. You can save helper code away in .csx files or in your project for later evaluation and use in the REPL. Your code snippets might grow into a little program or utility that you want to run now and then, which you can save in a .csx file. You can #load .csx files in the REPL to re-execute the same code at a later time.

An important aspect of the Interactive feature set is enabling you to keep simple programs simple. If you have a quick, one-off task that just needs, say, 10-20 lines of code to open a file, manipulate some data, or test some code, you can open a .csx file and write the code you need. Then run the code with csi.exe. You do not have to jump through the VS ceremonial hoops to create a program, compile it, then execute the resulting .exe. By default, csi.exe uses the same references and 'using's that a console application uses, but you can use #r to add other references in your script file. A script file is a self-contained simple program that may have started as little snippets of code in the REPL. When you invoke csi.exe, you can pass multiple .csx files (and even .cs files) on the command line which is useful if you have a library of top-level functions you commonly use with different main scripts that use the library. The whole idea is to let you work in a simple way when simple text-based code assets are easy to manage or execute as part of a build script, file utility, etc.

Lastly, with the ability to execute snippets of code and cumulatively build up execution context, it is very natural to want to host the C# execution engine as a way to enable scripting of your .NET applications. You can then take snippets of code or files from users and execute them in a context where free identifiers are bound to public members on a host object model instance. The host application can decide what to expose to user script code for controlling the application, adding commands, or hooking events.

Scripting walkthroughs:

Introduction to Scripting

Scripting a Paint-like Application

You can download the “Roslyn” CTP and try it out today!  The REPL installs as a new tool window in VS 2010.

Author: "CSharpFAQ" Tags: "C#, roslyn, REPL"
Send by mail Print  Save  Delicious 
Date: Monday, 23 Jan 2012 17:00

by Alan Berman

The new Async feature in Visual Studio makes it easy to code asynchronous method calls. To make synchronous code asynchronous, you can simply call an asynchronous method instead of a synchronous method and add a few keywords to the code, as shown in the examples below.  You no longer need to define continuations to capture what happens when the asynchronous operation finishes, which can otherwise complicate the code.

Even with the simplicity, why make file access calls asynchronous?  Aren't they fast enough already?  Here are reasons to consider:

  • Asynchrony makes UI applications more responsive. It allows the UI thread that launches the operation to be used for other things. If the UI thread is blocked by executing code that takes a long time (i.e. more than, say, 50 milliseconds), the UI may freeze until the I/O is complete and the UI thread is again able to process keyboard and mouse input and other events.
  • Asynchrony improves the scalability of ASP.NET and other server-based applications by reducing the need for threads.  If file operations are synchronous and a hundred file access operations are happening at once, then a hundred threads are needed.  Asynchronous operations often do not require use of a thread during the wait.  They use the existing I/O completion thread briefly at the end.
  • Even though a file access operation has very low latency now, it's possible that latency may greatly increase in the future. For example, a file may later be moved to a server that's across the world.
  • The added overhead of using the Async feature is small.
  • Asynchronous tasks can easily be run in parallel.

Running the Examples

Note: The examples in this blog do not apply to Metro style apps, which are Windows 8 applications that are tailored for touch interaction and are full screen.  For information on using Async for file access in Metro style apps, see .NET for Metro style apps overview and File and Stream I/O.  For some good examples of Metro file I/O, you can download the File Access Sample provided on the Dev Center.

The examples below run in either Visual Studio 11 Developer Preview or the Async CTP for Visual Studio 2010 SP1.  Both can be accessed from Visual Studio Asynchronous Programming. If you use the Async CTP for Visual Studio 2010, add a reference to AsyncCtpLibrary.dll, which is in My Documents\Microsoft Visual Studio Async CTP\Samples.

Include the following using statements in the console examples below.

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;

Use of the FileStream Class

The examples below use the FileStream class, which has an option that causes asynchronous I/O to occur at the operating system level.  In many cases, this will avoid blocking a ThreadPool thread.  To enable this option, you must specify the useAsync=true or options=FileOptions.Asynchronous argument in the constructor call.

StreamReader and StreamWriter do not have this option if you open them directly by specifying a file path. StreamReader/Writer do have this option if you provide them a Stream that was opened by the FileStream class. Note that asynchrony provides a responsiveness advantage in UI apps even if a thread pool thread is blocked, since the UI thread is not blocked during the wait.

Writing Text

The following example writes text to a file.  At each await statement, the method immediately exits.  When the file I/O is complete, the method resumes at the statement following the await statement.  Note that the async modifier is in the definition of methods that use the await statement.

static void Main(string[] args)
{
    ProcessWrite().Wait();
    Console.Write("Done ");
    Console.ReadKey();
}

static Task ProcessWrite()
{
    string filePath = @"c:\temp2\temp2.txt";
    string text = "Hello World\r\n";

    return WriteTextAsync(filePath, text);
}

static async Task WriteTextAsync(string filePath, string text)
{
    byte[] encodedText = Encoding.Unicode.GetBytes(text);

    using (FileStream sourceStream = new FileStream(filePath,
        FileMode.Append, FileAccess.Write, FileShare.None,
        bufferSize: 4096, useAsync: true))
    {
        await sourceStream.WriteAsync(encodedText, 0, encodedText.Length);
    };
}

Reading Text

The following example reads text from a file.  The text is buffered and, in this case, placed into a StringBuilder.  Unlike in the previous example, the evaluation of the await produces a value.  The ReadAsync method returns a Task<Int32>, so the evaluation of the await produces an Int32 value (numRead) that is returned after the operation completes..

static void Main(string[] args)
{
    ProcessRead().Wait();
    Console.Write("Done ");
    Console.ReadKey();
}

static async Task ProcessRead()
{
    string filePath = @"c:\temp2\temp2.txt";

    if (File.Exists(filePath) == false)
    {
        Console.WriteLine("file not found: " + filePath);
    }
    else {
        try {
            string text = await ReadTextAsync(filePath);
            Console.WriteLine(text);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }
}

static async Task<string> ReadTextAsync(string filePath)
{
    using (FileStream sourceStream = new FileStream(filePath,
        FileMode.Open, FileAccess.Read, FileShare.Read,
        bufferSize: 4096, useAsync: true))
    {
        StringBuilder sb = new StringBuilder();

        byte[] buffer = new byte[0x1000];
        int numRead;
        while ((numRead = await sourceStream.ReadAsync(buffer, 0, buffer.Length)) != 0)
        {
            string text = Encoding.Unicode.GetString(buffer, 0, numRead);
            sb.Append(text);
        }

        return sb.ToString();
    }
}

Control Flow

While it's easy to make method calls asynchronous, it helps to know what actually happens when the program reaches an await statement.

The original example had the statement "await sourceStream.WriteAsync...".  That's a contraction of  these two statements:  "Task theTask = sourceStream.WriteAsync…" and "await theTask".  The first statement causes a task to be returned and file processing to start.  The second statement with the await causes the method to immediately exit (returning a different task).  When the file processing later completes, execution returns to the statement following the await.

The following example does the same thing as the "Writing Text" example, however it splits the await statement into two statements and adds console output to assist in understanding the sequence.

static void Main(string[] args)
{
    ProcessWrite2().Wait();
    Console.Write("Done ");
    Console.ReadKey();
}

static Task ProcessWrite2()
{
    string filePath = @"c:\temp2\temp2.txt";
    string text = "Hello World\r\n";

    Task theTask = WriteTextAsync2(filePath, text);

    ShowInfo(theTask, "In ProcessWrite2 before wait");
    return theTask;
}

static async Task WriteTextAsync2(string filePath, string text)
{
    byte[] encodedText = Encoding.Unicode.GetBytes(text);

    using (FileStream sourceStream = new FileStream(filePath,
        FileMode.Append, FileAccess.Write, FileShare.None,
        bufferSize: 4096, useAsync: true))
    {
        Task theTask = sourceStream.WriteAsync(encodedText, 0, encodedText.Length);

        ShowInfo(theTask, "In WriteTextAsync2 before await");
        await theTask;
        ShowInfo(theTask, "In WriteTextAsync2 after await");
    };
}

static void ShowInfo(Task theTask, string message)
{
    Console.Write(message.PadRight(32) + " ");
    Console.Write("task " + theTask.Id.ToString() + " ");
    Console.Write("\n");
}

// Console output:
// In WriteTextAsync2 before await task 1
// In ProcessWrite2 before wait task 2
// In WriteTextAsync2 after await task 1
// Done

 

Parallel Asynchronous I/O

The following example demonstrates parallel processing by writing 10 text files.  For each file, the WriteAsync method returns a task.  Each task is added to a list of tasks.  The "await Task.WhenAll(tasks)" statement exits the method and resumes within the method when file processing is complete for all of the tasks.

For the Visual Studio 2010 Async CTP, use TaskEx.WhenAll instead of Task.WhenAll.

The example closes all FileStream instances in a finally block after the tasks are complete. If each FileStream was instead created in a using statement, the FileStream might be disposed of before the task was complete.

Note that any speedup is almost entirely from the parallel processing and not the asynchronous processing.  The advantages of asynchrony are that it does not tie up multiple threads, and that it does not tie up the user interface thread.

static void Main(string[] args)
{
    ProcessWriteMult().Wait();
    Console.Write("Done ");
    Console.ReadKey();
}

static async Task ProcessWriteMult()
{
    string folder = @"c:\temp2\";
    List<Task> tasks = new List<Task>();
    List<FileStream> sourceStreams = new List<FileStream>();

    try {
        for (int index = 1; index <= 10; index++)
        {
            string text = "In file " + index.ToString() + "\r\n";

            string fileName = "thefile" + index.ToString("00") + ".txt";
            string filePath = folder + fileName;

            byte[] encodedText = Encoding.Unicode.GetBytes(text);

            FileStream sourceStream = new FileStream(filePath,
                FileMode.Append, FileAccess.Write, FileShare.None,
                bufferSize: 4096, useAsync: true);

            Task theTask = sourceStream.WriteAsync(encodedText, 0, encodedText.Length);
            sourceStreams.Add(sourceStream);

            tasks.Add(theTask);
       }
    
        await Task.WhenAll(tasks);
    }

    finally {
        foreach (FileStream sourceStream in sourceStreams)
        {
            sourceStream.Close();
        }
    }
}

The WriteAsync and ReadAsync methods allow you to specify a CancellationToken, which can be used to cancel the operation mid-stream.  The Simultaneous Async Tasks blog has an example of cancellation.  Additional information is provided in the Cancellation topic.

Thanks to Stephen Toub for providing technical guidance.

See Also 

Resources

Author: "CSharpFAQ" Tags: ".NET Framework, C#, parallel-programming..."
Send by mail Print  Save  Delicious 
Date: Friday, 02 Dec 2011 20:56

by Brian Rasmussen

In this post we take a look at how the Roslyn Scripting API can enable applications to evaluate code at runtime. While this has been possible since the dawn of .NET through the use of Reflection, Lightweight Code Generation, CodeDom, etc., it has never been particularly easy. All of these mechanisms are either hard to use, require MSIL knowledge, or just have inherent limitations.

Roslyn not only makes dynamic code evaluation a lot easier, it also provides the necessary APIs to implement a fully featured scripting experience. This post covers the basics of the Scripting API in Roslyn. For an example of how Roslyn can be used to implement a rich environment for entering and executing code at runtime take a look at the C# Interactive window implemented in the Roslyn CTP. The C# Interactive window provides syntax highlighting, intellisense, and even refactoring for code supplied at runtime.

This post uses C# as an example because that is what Roslyn supports for scripting in this first CTP. 

The Basics

Let’s start by looking at a very simple example. Let’s just execute some code dynamically. To do that all we need is an instance of the ScriptEngine class. Specifically we need the C# version defined in Roslyn.Scripting.CSharp. All we have to do is create an instance of ScriptEngine and call the Execute method with the code to be evaluated. The Roslyn scripting version of Hello World is as simple as:

using Roslyn.Scripting.CSharp;
 
namespace RoslynScriptingDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            var engine = new ScriptEngine();
            engine.Execute(@"System.Console.WriteLine(""Hello Roslyn"");");
        }
    }
}

The solution needs references to Roslyn.Compilers and Roslyn.Compilers.CSharp.

Notice, we did not have to use APIs that take MSIL or that carefully build up a tree of code that then needs to be compiled and executed. We can simply send the ScriptEngine text snippets of the code we write all the time. The ScriptEngine takes care of the rest to execute it.

Execution Context

Unfortunately the code above does have a few limitations. The first of which is that there’s no cumulative execution context, so if we define a variable as part of one code snippet and then try to access the variable from another code snippet, we will get an exception. For example, if we change the body of Main to something like this:

var engine = new ScriptEngine();
 
engine.Execute(@"var a = 42;");
engine.Execute(@"System.Console.WriteLine(a);");

We will get a compilation error from the scripting engine as the statements are treated as separate compilations. Fortunately, the Scripting API provides the Session type that can be used as an execution context when calling Execute. A session stores the context of a series of submissions, so by providing a session we can execute the code above and get the expected result.

using Roslyn.Scripting.CSharp;
using Roslyn.Scripting;
 
namespace RoslynScriptingDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            var engine = new ScriptEngine();
            var session = Session.Create();
 
            engine.Execute(@"var a = 42;", session);
            engine.Execute(@"System.Console.WriteLine(a);", session);
        }
    }
}

We can even define a new method, store it in the session, and then invoke it like this.

engine.Execute(@"void Foo() { System.Console.WriteLine(""Foo""); }", session);
engine.Execute(@"Foo();", session);

Interacting with the Host Application

However, we still cannot interact with the hosting application. Obviously scripting is of limited use if the user supplied code cannot interact with the application somehow. To address this we need to provide a host object to the session.

The code submissions will automatically have access to any public members of the host object. To supply a host object, we pass in an instance of any type we would like to use as an interface between the host application and the session. Furthermore, we have to make the ScriptEngine aware of this type as well. To do that we pass in a reference to the assembly defining our host object type. With that the setup code now looks as follows:

var hostObject = new HostObject();
var engine = new ScriptEngine(new[] { hostObject.GetType().Assembly.Location });
var session = Session.Create(hostObject);

The host object can be of any type. The ScriptEngine binds any free identifier to public members of the type, as if the type's member names were globally accessible from the script. For the sake of this demo, let’s just make it as simple as possible.

public class HostObject
{
    public int Value = 0;
}

With the code above, we can now access the Value field on our hostObject instance like this:

engine.Execute(@"Value = 42;", session);
engine.Execute(@"System.Console.WriteLine(Value);", session);

Notice how the instance's members are implicitly available within the session. We simply access any public member on the instance.

The examples we have been looking at so far are really simple, so let’s round off this introduction by adding some functionality that resembles what an application might do with the scripting API. Imagine we have a Report type like the one listed below.

// This will act as our host object
public class Report
{
    // Internal state
    private readonly List<int> values = new List<int>();
    private int result;
 
    // Encapsulate the internal data structure
    public void AddValue(int value)
    {
        values.Add(value);
    }
 
    // Allow read-only enumeration of values
    public IEnumerable<int> Values { get { return values; } }
 
    // User code will provide the implementation for these methods
    public Action GetValues;
    public Func<int> CalculateResult;
 
    // This method may be called by both the host application and the user code
    public void PrintResult()
    {
        var get = GetValues;
        if (get != null)
        {
            get();
        }
 
        var calc = CalculateResult;
        if (calc != null)
        {
            result = calc();
        }
 
        Console.WriteLine("The result of the calculation is {0}", result);
    }
}

The class stores an internal list of numbers and a result. It provides an AddValue method to populate the list and a read-only iterator. The result can be printed by calling the PrintResult method. User-supplied code determines how the list is actually populated and how the result is calculated.

The Report class exposes two delegate types, GetValues and CalculateResult for this purpose. When PrintResult is called it invokes the delegates to populate the list of values and calculate the result. Our simple application may look something like this:

static void Main(string[] args)
{
    var report = new Report();
    var engine = new ScriptEngine(new[] { 
        "System.Core", report.GetType().Assembly.Location });
    var session = Session.Create(report);
 
    engine.Execute(@"using System.Linq;", session);
    engine.Execute(
        @"GetValues = () => { for(int i = 1; i <= 3; i++) AddValue(i); };",
        session);
    engine.Execute(@"CalculateResult = () => Values.Sum();", session);
 
    report.PrintResult();
}

Admittedly this is still a simple example, but it does illustrate how script code can be used to customize our host application.

Notice how we can assign anonymous methods to the delegate members, and the host application can call them. Also, notice how we can access the LINQ extension method Sum in the user supplied code. To enable this we need to let ScriptEngine reference System.Core and import the System.Linq namespace.

That completes the overview of how to use Roslyn to add scripting support to an application. For more information on the Roslyn Scripting API please see the walkthroughs and The Roslyn Project Overview.

About the author

Brian is a Senior SDET at Microsoft working on the C# and VB language services in Roslyn. Before joining Microsoft Brian was a Microsoft MVP for Visual C# for four years. Brian can be found on Twitter (@kodehoved).

Author: "CSharpFAQ" Tags: "C#, roslyn"
Send by mail Print  Save  Delicious 
Date: Wednesday, 23 Nov 2011 23:10

by Kevin Pilch-Bisson

I’m back again, to move along to the next stage of the compiler pipeline, and take a look at working with Symbols in the using the Roslyn CTP.

The Roslyn CTP’s symbol API provides a top-down view of all the symbols available. Before we get to symbols though, we need to start looking at how to give the compiler enough context to tell us about symbols. While syntax trees are mostly context free and can stand on their own, in order to learn about symbols we need to have a collection of syntax trees, the references passed to the compiler, and any options in effect. In Roslyn, we use the Compilation type to group these things together. Conceptually, a Compilation represents one invocation of the csc.exe command line, or a single project in Visual Studio.

Let’s start by creating a compilation that includes something like the simple file we used last time when talking about syntax trees:

using System;
using System.IO;
using System.Linq;
using Roslyn.Compilers;
using Roslyn.Compilers.CSharp;

class Program
{
    static void Main(string[] args)
    {
        var syntaxTree = SyntaxTree.ParseCompilationUnit(@"
class C
{
    static void Main()
    {
        if (true)
            Console.WriteLine(""Hello, World!"");
    }
}");

        var compilation = Compilation.Create("test.dll",
            syntaxTrees: new[] { syntaxTree },
            references: new []
                {
                    new AssemblyFileReference(typeof(object).Assembly.Location),
                    new AssemblyFileReference(typeof(Enumerable).Assembly.Location),
                });
    }
}
        

Aside: You’ll find that many parts of the Roslyn APIs use optional arguments, and it’s convenient to call them with named parameters. The reason for this is that we’re exposing an immutable API, so we want to allow you to specify all the options right at creation time, but we don’t want to force you to type them all. In a mutable model, we’d probably leave many of these things out of the constructors/factory methods and allow you to set them via properties.

Now that we’ve got a Compilation, what are the interesting things to do with it? Well, there are a few.

“Change” it

Like SyntaxTrees and many other parts of the Roslyn API, Compilations are immutable, so we can’t really change them. However, there are methods like AddReferences() and RemoveSyntaxTrees(), that will return a new Compilation object with those changes (just like string.Append)

Find errors and warnings

The Compilation object makes it possible for us to programmatically determine what errors and warnings exist in a piece of code. There are two different APIs for this on the Compilation object. First of all you can call GetDiagnostics, which returns all of the errors for the Compilation. This requires doing a significant amount of work (almost as much as just compiling), so it can take a while.

In addition to GetDiagnostics, the Compilation has a method named “GetDeclarationDiagnostics”. This is meant to be a somewhat less expensive call, and one that doesn’t throw away the results of its work. You can think of the declaration diagnostics as all the errors that happen outside the curly braces of method bodies and property accessors. Finding them requires completely filling out the symbol table of the Compilation, but it doesn’t require looking at method bodies. In contrast, GetDiagnostics first calculates the declaration diagnostics, and then binds each method body in turn. Keeping the fully bound form of every method would take a lot of memory for a large Compilation, and so the bound information is released once the diagnostics have been collected.

var diagnostics = compilation.GetDiagnostics();
foreach (var d in diagnostics)
{
    var lineSpan = d.Location.GetLineSpan(usePreprocessorDirectives: true);
    var startLine = lineSpan.StartLinePosition.Line;
    Console.WriteLine("Line {0}: {1}", startLine, d.Info.GetMessage());
}

Compile it!

We can write out the bytes to an assembly using Emit(). In case we want to Emit if possible, and display diagnostics if not, the Emit call returns a result that includes the diagnostics. This means that we can skip a call to GetDiagnostics before trying Emit, which means that nothing has to look at each method body twice.

using (var file = new FileStream("test.dll", FileMode.Create))
{
    var result = compilation.Emit(file);
}
        

Examine the symbol table

One of the most interesting things we can do is look at the symbol table and examine the types and members inside of it, sort of the way you would do with Reflection.

To examine every type in the Compilation, you can start with the GlobalNamespace property of the Compilation. One thing to note is that the Compilation’s GlobalNamespace is what the compiler uses when doing lookups, so it includes everything defined in the Compilation and in its references. If you want to see only things that are actually defined in the Compilation, you can look at the “Assembly.GlobalNamespace” instead. Let’s look at an example where we find every member that contains the letter “a” in its name:

ReportMethods(compilation.Assembly.GlobalNamespace);
        

and

private static void ReportMethods(NamespaceSymbol namespaceSymbol)
{
    foreach (var type in namespaceSymbol.GetTypeMembers())
    {
        ReportMethods(type);
    }

    foreach (var childNs in namespaceSymbol.GetNamespaceMembers())
    {
        ReportMethods(childNs);
    }
}

private static void ReportMethods(NamedTypeSymbol type)
{
    foreach (var member in type.GetMembers())
    {
        if (member.CanBeReferencedByName &&
            member.Name.Contains("a"))
        {
            Console.WriteLine("Found {0}", member.ToDisplayString());
        }
    }

    foreach (var nested in type.GetTypeMembers())
    {
        ReportMethods(nested);
    }
}
        

Note the handy “CanBeReferencedByName” property, which saves us from including things like accessor methods for a property, that exist in the symbol table, but which users aren’t allowed to actually name. Also, take note of the “ToDisplayString()” extension method, which allows you to generate various forms of symbol names, including some human readable ones.

Alternatively, if there is a specific type you want to find, you can use the GetTypeByMetadataName method. We needed a way to represent fully qualified names type names that include generic arity and nestedness. Rather than define our own format, we decided to use the metadata format, which means that to use this API, you’ll need to use + to separate nested types, and encode the generic arity with `n where n is the number of type arguments. For example, to look up the nested Enumerator type in List<T>, we’d use a string like “System.Collections.Generic.List`1+Enumerator”.

One question we get is that if this model is similar to reflection, why isn’t it easier to get to the System.Type for a TypeSymbol? The reason is that the compiler may be targeting a different runtime than the one that your code is running on – consider a compilation for a Silverlight project for example. There is no way to load a System.Type for some type in the reference assembly to mscorlib.dll. At best you would find the corresponding System.Type in the desktop CLR, which may or may not be what you need.

Analyze specific parts of it

It may be interesting to pick a particular expression and see what method is going to be invoked, or similar semantic questions. We’ll look at this in more detail in the next post, but if you want to get a head start, take a look at the GetSemanticModel method on Compilation, and it’s resulting SemanticModel object.

Author: "CSharpFAQ" Tags: "roslyn"
Send by mail Print  Save  Delicious 
Date: Saturday, 19 Nov 2011 02:20

Hi All! A few weeks ago, we announced the Microsoft "Roslyn" CTP. I hope many of you have had a chance to download the CTP and take it for a spin :) If you haven’t, do give it a try.

To recap – in the Roslyn CTP, we are previewing a powerful set of language services APIs that you can use within your apps to reason about C# and VB code. We are also previewing IDE extensibility points for C# and VB that will allow you to build rich code refactorings, quick fixes etc. that run inside Visual Studio.

In this post, I just wanted to point out a couple of tools that you may be interested in if you are working with the CTP – the Roslyn Syntax Visualizers. You can read more about these visualizers and how to install and use them on the following blog post – http://blogs.msdn.com/b/visualstudio/archive/2011/10/19/roslyn-syntax-visualizers.aspx

The visualizers ship as samples in the CTP and allow you to visually inspect and explore Roslyn Syntax Trees (below screenshot shows an example). You can use these visualizers as debugging aids when you develop your own applications / code refactorings using the Roslyn APIs.

image

Happy Coding! :)

Shyam Namboodiripad
Software Development Engineer in Test (Roslyn Compilers Team)

Author: "CSharpFAQ" Tags: "C#, Visual Studio, C# compiler, roslyn, ..."
Send by mail Print  Save  Delicious 
Date: Thursday, 03 Nov 2011 21:51

By Kevin Pilch-Bisson

As promised back when we released the Roslyn CTP, here is the first of a series of blog posts that help explain the various parts of the Roslyn API. If you don’t have the Roslyn CTP, you can get it from our MSDN page, and install it on top of Visual Studio SP1 and the VSSDK. If you want to get into using the Roslyn CTP seriously, I highly recommend taking a look at the overview document, and the various walkthroughs that we’ve put together.

Properties

The Syntax API in Roslyn has three two key properties. First, it is a full-fidelity model. Every character of a source file is represented in the API, which means that it also round trips. You can parse a source file, call ToString on the resulting SyntaxTree and get the original file text back.

Key Types

The key types in the Syntax API of the Roslyn CTP are: SyntaxNode, SyntaxToken and SyntaxTrivia. SyntaxNode represents a non-terminal node in the language grammar, and is an immutable object. There are a variety of different derived types for different language elements, and also a Kind property that identifies what a particular SyntaxNode represents. SyntaxNodes are arranged into a tree, connected by the Parent and ChildNodes properties. Each type derived from SyntaxNode also includes named properties for element of that particular node type. For example, an IfStatementSyntax has properties for the IfToken, OpenParenToken, Condition, CloseParenToken, Statement, and ElseClauseOpt.

SyntaxToken objects represet the terminals of the language grammar. They never have children, but do have a Parent property that is always a SyntaxNode. For performance reasons, SyntaxToken is a struct type. You can use the Kind property to determine what sort of token something is.

Finally, things like whitespace and comments that can appear anywhere in a source file are represented as SyntaxTrivia. Each SyntaxTrivia is attached to a single token, as either LeadingTrivia or TrailingTrivia. SyntaxTrivia does not have a parent property, but it is possible to get the associated token via the Token property. Like SyntaxToken, SyntaxTrivia is a struct for performance reasons.

Parsing

Okay, enough talk, let’s see some code. First off, let’s see how we can get a hold of the SyntaxTree, and what it looks like. To start off with, you can parse some text using SyntaxTree.ParseCompilationUnit:

using System;
using System.Linq;
using Roslyn.Compilers;
using Roslyn.Compilers.CSharp;

class Program
{
    static void Main(string[] args)
    {
        var syntaxTree = SyntaxTree.ParseCompilationUnit(@"
using System;
class C
{
    static void M()
    {
        if (true)
            Console.WriteLine(""Hello, World!"");
    }
}");
        var ifStatement = (IfStatementSyntax)syntaxTree.
            Root.
            DescendentNodes().
            First(n => n.Kind == SyntaxKind.IfStatement);
        Console.WriteLine("Condition is '{0}'.", ifStatement.Statement);
    }
}
        

In this example, we parse some simple text and look at the resulting SyntaxTree. In this case, we search through the syntax tree looking for IfStatements and grab the first one we find. We cast that the the more strongly typed IfStatementSyntax type, and then we can look at the properties specific to if statements. In this case, we looked at “Statement” which is a SyntaxNode that represents the statement to execute if the condition is true.

Construction

Sometimes you don’t want to parse existing source code to build up a SyntaxTree. Instead you want to create brand new SyntaxNodes. The most common case for this is that you want to add or change some existing syntax, and you need the new things to transform to. With the Roslyn CTP, the way you create new SyntaxNode objects is through the set of factory methods on the “Syntax” class.

var newStatement = Syntax.ExpressionStatement(
    Syntax.InvocationExpression(
        Syntax.MemberAccessExpression(
            SyntaxKind.MemberAccessExpression,
            Syntax.IdentifierName("Console"),
            name: Syntax.IdentifierName("WriteLine")),
        Syntax.ArgumentList(
            arguments: Syntax.SeparatedList<ArgumentSyntax>(
                Syntax.Argument(
                    expression: Syntax.LiteralExpression(
                        SyntaxKind.StringLiteralExpression,
                        Syntax.Literal(
                            text: @"""Goodbye everyone!""",
                            value: "Goodbye everyone!")))))));
        

Here, we’re constructing a new statement to represent a call to “Console.WriteLine("Goodbye everyone!");”. As you can see, this involves specifying quite a lot of detail. That’s one of the drawbacks of a full-fidelity model, it also means that you need specify all of those details when you create things. If you look closely, you can also see that in some places I’m using C# 4.0’s named arguments. The reason for this is that many parameters in the Syntax construction APIs are defined to be optional. The reason for optional parameters is that when possible, you don’t need to specify a detail. For example, many tokens are always exactly the same (like keywords, punctuation, etc). If you omit an argument for them, a default version will be constructed for you. If you’d like, you CAN specify every token, including triva for each one.

One thing you can do to reduce the verbosity is to sneak in calls to the various Syntax.Parse?? methods for elements of structure you are building up. This way, you can inline the code you want to have in a string instead of specifying the entire structure.

Rewriting

The next major piece of functionality in the Syntax API is re-writing, or modifying syntax trees. There are two approaches to this. The simplest is to just use one of the Replace APIs on SyntaxNode. The idea is that you get back a new tree, but with one of the descendants replaced.

var newTree = syntaxTree.Root.ReplaceNode(
    ifStatement.Statement,
    newStatement).Format();

Console.WriteLine(newTree);
          
We’ve successfully replace the body of the if statement. Because the trees are immutable, the original “SyntaxTree.Root” is completely unaffected. The newTree variable really is a brand new tree, but under the covers we actually re-use a lot of the data in an invisible fashion to be more efficient both in time and memory. Of note in the sample is the call to “Format()” on the new tree, which will apply a default formatting, and ensure that there is whitespace where there needs to be for the tree to round trip.

In some cases where you want to re-write multiple nodes, you might want more control over how the tree gets changed. To support this, the Roslyn CTP includes an abstract SyntaxRewriter class. I’ll give you a simple example that rewrites the tree above so that “M” is named “Main”, but there are obviously more interesting things that can be done here:

class Rewriter: SyntaxRewriter
{
    protected override SyntaxToken VisitToken(SyntaxToken token)
    {
        if (token.Kind != SyntaxKind.IdentifierToken ||
            token.GetText() != "M")
        {
            return token;
        }

        return Syntax.Identifier("Main");
    }
}
        

And you can use it like this:

var rewriter = new Rewriter();
newTree = rewriter.Visit(newTree);
Console.WriteLine(newTree);
        

In this example, I’ve only used “VisitToken”, but there are actually a TON of “Visit” methods that you can override to rewrite specific types of nodes in a tree.

Closing

We’ve taken a brief look at some of the key concepts and types of the Syntax portion of the API in the Roslyn CTP, including parsing, constructing node from scratch, and rewriting existing nodes. Next time, we’ll move to the next stage of the compilation pipeline, and take a look at how Symbols are exposed in Roslyn.

Author: "CSharpFAQ"
Send by mail Print  Save  Delicious 
Date: Wednesday, 19 Oct 2011 21:00

By Kevin Pilch-Bisson

As Soma mentioned earlier, today we’ve made a Community Technology Preview (CTP) available for download! The Roslyn project is a forward looking effort to make the wealth of language understanding that the compiler generates available to developers in other scenarios. A number of us have been working hard on getting enough of these pieces put together to have something to share with you, and we’re thrilled to be able to do that today.

The foundation of this work is a new C# compiler, written in C# (and a new VB compiler written in VB too, see the VB Team blog for details). This compiler is written as a library that exposes a rich public API. Next up is a new language service written purely using that public API and exposing its own extensibility points to allow 3rd parties to do amazing things inside Visual Studio with that language understanding.

Resources

The Visual Studio blog gives a good overview of the various pieces that the CTP installs, but I thought I’d use this space to look at a little more code that uses the API.

The Roslyn MSDN page contains pointers to an overview document that explains the basic concepts in the Roslyn API in greater detail. There are also several guided walkthroughs that each dive deeper into a particular area of the API. Finally if you install the CTP, there are numerous samples installed to the “My Documents” folder that you can build, run and experiment with.

Watch this space in the next few weeks for a series of posts that will each explore one bit of the API.

Feedback

We’re very interested in your feedback about the Roslyn project! Because it’s early in the project we’re most interested in feedback about the API and general direction. Please get involved in the discussion about Roslyn on our forums. You can also file bugs on our Connect site. Finally, some of the team members are also on Twitter, and will be keeping an eye on the #RoslynCTP hashtag if that is more convenient for you.

Disclaimer

Please note: This is a technology preview and there are known limitations. While the shape of the public API surface is complete, only a subset of the C# and Visual Basic languages have been implemented at this time in the current CTP.

About the author

Kevin is a Development lead at Microsoft responsible for the C# and VB language services in Roslyn. He’s been at Microsoft for 9 years, and has spent all of it working in the language and IDE space. Kevin is a graduate of the University of Waterloo. He used to blog at http://blogs.msdn.com/b/kevinpilchbisson, but has been spending more time on Twitter (@Pilchie) and on getting Roslyn into your hands lately.

Author: "CSharpFAQ" Tags: "IDE, C#, C# compiler, roslyn"
Send by mail Print  Save  Delicious 
Date: Thursday, 01 Sep 2011 00:02

By Emily Gibson

New! C# 2010 Soup to Nuts Series

Explore this webcast series on Visual C# 2010 presented by Developer Evangelist, Bill Steele. Learn about class libraries, operator basics, branching and looping, and more as Bill dives deep into this fantastic language.

Part 1: Introduction

WMV Download | Zune | WMA | MP3

Watch this Entire Series:

Part 1: Introduction
Part 2: Visual C# Express
Part 3: Class Libraries
Part 4: Visual C# Program Structure
Part 5: Language Fundamentals
Part 6: Branching and Looping
Part 7: Classes and Objects
Part 8: Operator Basics
Part 9: Basic Debugging
Part 10: Arrays and Collections

Author: "CSharpFAQ" Tags: "C#"
Send by mail Print  Save  Delicious 
Date: Monday, 15 Aug 2011 18:36

Some great new video's on MSDN showing how to do async programming using the Async CTP.

http://msdn.microsoft.com/en-us/vstudio/hh378091.aspx

There are different versions of video's for both VB and C#. This is a great opportunity to see the power of the new Async languages featuresand follow through a series of examples showing how easy it is to use the new feature.

Also, the MSDN forums have one specifically dedicated to the Async CTP which compilers team member are monitoring to help answer any questions.

http://social.msdn.microsoft.com/Forums/en-US/async/threads

Spotty

Author: "CSharpFAQ" Tags: "C#/VB.NET Equivalents, Visual Studio Asy..."
Send by mail Print  Save  Delicious 
Date: Wednesday, 13 Apr 2011 16:13

By Jeremy Meng

Visual Studio Async CTP (SP1 Refresh) is available now! You are welcome to download and try it out!

Thanks to the new Async feature coming in Visual Basic and C# it has never been so easy to write asynchronous code. With the newly introduced async and await keywords you can make asynchronous calls without having to create callback functions, sign them up to some ****Completed events, retrieve results from EventArgs by yourself. Visual Basic and C# compiler will do the plumbing work for you.

I hope that the following example can help you get basic ideas on how the Async feature makes writing responsive applications easier.

Here is a simple WPF application to get you started with Async in C#. This WPF app has a label, a button, and a checkbox on its UI. When the button is clicked, the application will perform a query over the network (for example, downloading files from the internet, querying data from a database, etc.) After the query is done, the label will be updated to show the length of the returned string data.

The event handler for button click:

private void button1_Click(object sender, RoutedEventArgs e)

{

    UpdateLabel();

}


async void UpdateLabel()

{

    NetworkClass nc = new NetworkClass();

    int i = 0;

    i = await nc.MethodQueryingNetworkAsync();

    label1.Content = "Length: " + i;

}

 

The code for MethodQueryingNetworkAsync() is like below:

async public Task<int> MethodQueryingNetworkAsync()

{

    // Querying a slow website with network latency so that

    // the result comes back after a certain amount of time

    WebClient wc = new WebClient();

    string content = await wc.DownloadStringTaskAsync(
       
new Uri("http://some.slow.website/"));

    return content.Length;

}

 

Run the application and click on the button, you will still be able to toggle the checkbox on UI while the network query is executing. When the downloading is finished, the label will be updated to show the length of the query result. During the query execution, the UI is completely responsive.

What’s new in Visual Studio Async CTP SP1 Refresh?

  • It is compatible with Visual Studio 2010 SP1 and Windows Phone 7. The previous Async CTP only works for Visual Studio 2010 RTM.
  • More efficient Async methods!

We changed the old pattern of GetAwaiter/BeginAwait/EndAwait with the new pattern of GetAwaiter/IsCompleted/OnCompleted/GetResult. This provides better performance especially if the task we are awaiting had already completed. We also make exception behaviors uniform in void-returning async methods (Async Subs in Visual Basic).

  • Many bug fixes since the release of the previous Async CTP. Thanks for the feedbacks from the community! Please let us know what you think!

For more details, read on Lucian’s blog. Welcome to Async and happy asynchronous coding!

Author: "CSharpFAQ" Tags: "C#, Visual Studio Async CTP, async, awai..."
Send by mail Print  Save  Delicious 
Date: Monday, 28 Mar 2011 18:37

This blog post explains how to kick off a debugger in a remote machine, programmatically. We are going to use WMI interfaces to achieve this. Use WMI, to start the debuggee process and attach a registered debugger to it using WMI. I have given a sample code below.

This Code assumes that we have the ConsoleApplication1 process running in the Machine1(debuggee Machine). On executing this code , the registered Debugger instance will be attached to “ConsoleApplication1” process. If you have multiple debuggers registered in the debuggee machine, then “Select Debugger” dialog would come up. We can use this method to attach Debugger to any kind of processes/services.

 

        ConnectionOptions options = new ConnectionOptions();

        ManagementScope scope = new ManagementScope("\\\\machine1\\root\\cimv2", options);

        scope.Connect();

      

        ObjectQuery oQuery = new ObjectQuery("Select * from Win32_Process where Name Like 'ConsoleApp%'");

        //Execute the query

        ManagementObjectSearcher objSearcher = new ManagementObjectSearcher(scope,oQuery);

 

        //Get the results

        ManagementObjectCollection objReturnCollection = objSearcher.Get();

 

        foreach (ManagementObject oReturn in objReturnCollection)

        {

            if (oReturn["Name"].ToString().Equals("ConsoleApplication1.exe"))

            {

                object outparams = oReturn.InvokeMethod("AttachDebugger", null);

            }

        }

 This code reads through the active processes in the remote machine using WMI, and there is a build method of invoking the process while attaching a debugger to it. To learn more about using WMI, here.

Author: "CSharpFAQ" Tags: "debug, WMI, start debugger remotely"
Send by mail Print  Save  Delicious 
Date: Wednesday, 09 Feb 2011 00:55

Do you want to work on a product used by millions of developers around the world?  I do!  Come join me to deliver Visual Studio, the set of developer tools used across Microsoft and around the world.  We have open positions available across Test, Dev and PM at varying levels on many projects across Visual Studio Professional.  We’re looking for the most talented folks around to help us  deliver the core parts of Visual Studio, from the Shell & IDE, languages (VB/C#/F#), packaging & setup, to our future investments in C# & VB. 

Here are a list of our open positions.  We love referrals, let your friends know they can work on Visual Studio too!  To get more information, please submit your resume.

Visual Studio IDE/Platform Team

Team Position
IDE/Platform Software Development Engineer in Test 2
IDE/Platform Software Development Engineer in Test 2
IDE/Platform Software Development Engineer 2
IDE/Platform Program Manager 2

 

Visual Studio Pro Experience

Team Position
Pro Experience Software Development Engineer in Test 2
Pro Experience Software Development Engineer 2
Pro Experience Program Manager 2
Pro Experience ​Senior Program Manager
Pro Experience Senior Software Development Engineer

 

Codename Roslyn (compiler as a service)

Team Position
Roslyn Software Development Engineer in Test Lead
Roslyn Software Development Engineer 2

 

Visual Studio Project, Build & Windows focus

Team Position
Visual Studio Tools Software Development Engineer in Test 2

 

In case you’re not familiar with these core engineering roles at Microsoft, you can find more information out on the Microsoft Career Site.  Here are short descriptions of the roles:

  • Program Managers (PMs) transform visions into elegant designs that ultimately turn into products and solutions. Or, put more simply, we anticipate what customers want and translate that into what they get. Working closely with development, test, user experience, and marketing professionals, we identify requirements, set priorities, manage feature sets across product lifecycles, and author technical specifications and customer scenarios.
  • Testers (Software Development Engineers in Test –SDETs) “build it to break it.” We push products to their limit, making sure they perform to customer expectations and conform to the highest quality standards. In partnership with developers and program managers, and using C, C++, C#, and VB.NET, we write test cases and plan, design, develop, and maintain automation tools that isolate and debug problems.
  • Developers (Software Development Engineers – SDEs) write the code—C, C++, C#, and other programming languages—that turns concepts into new technologies and services. We are experts in feature design and feasibility, and we collaborate with program managers and test engineers to define features and ensure quality.

 

I hope to hear from you soon!

Peter Hauge [MSFT]

Author: "CSharpFAQ"
Send by mail Print  Save  Delicious 
Date: Monday, 08 Nov 2010 18:16

Learn about the upcoming changes to the Help Viewer planned for Visual Studio 2010 SP1.  Paul O’Rear, a Program Manager on the Library Experience team, describes the changes planned and demonstrates the new functionality of the viewer in an early build of Help Viewer 1.1.

See Microsoft Help Viewer – Updates Planned for Visual Studio 2010 SP1

image

You can learn more in The Story of Help in Visual Studio 2010 

--Kathleen

Author: "kmcgrath"
Send by mail Print  Save  Delicious 
Next page
» You can also retrieve older items : Read
» © All content and copyrights belong to their respective authors.«
» © FeedShow - Online RSS Feeds Reader