Thursday, December 24, 2009
Microsoft TechEd North America 2010 - Home
Wednesday, November 25, 2009
Now Available: patterns & practices Application Architecture Book
The Microsoft Application Architecture Guide, 2nd edition, is now available on Amazon and should be available on the shelf at your local bookstores soon. The PDF was downloaded ~180,000 times. This is the Microsoft platform playbook for application architecture. You can think of it as a set of blueprints, and as your personal mentor for building common types of applications on the Microsoft platform: mobile, RIA, services, and Web applications.
The backbone of the guide is an information model for the application architecture space. It's a durable and evolvable map to give you a firm foundation of principles, patterns, and practices that you can overlay the latest technologies. It's your "tome of know-how." While it's not a step-by-step for building specific applications, it is a pragmatic guide for designing your architecture, with quality attributes, key software principles, common patterns, and architectural styles in mind. It's holistic and focused on the key engineering decisions where you face your highest risks and most important choices.
Key Features of the Book
The book has several compelling features for slicing and dicing the application architecture body of knowledge:
- Canonical Frame. This describes at a meta-level, the tiers and layers that an architect should consider. Each tier/layer will be described in terms of its focus, function, capabilities, common design patterns and technologies.
- Application Types. These are canonical application archetypes to illustrate common application types: Mobile, Rich Client, RIA, Services, and Web applications. Each archetype is described in terms of the target scenarios, technologies, patterns and infrastructure it contains. Each archetype is mapped to the canonical app frame. They are illustrative of common application types and not comprehensive or definitive.
- Quality attributes. This is a set of qualities and capabilities that shape your application architecture: performance, security, scalability, manageability, deployment, communication, etc.
- Cross-cutting concerns. This is a common set of categories for hot spots for key engineering decisions: Authentication, Authorization, Caching, Communication, Configuration Management, Exception Management, Logging and Instrumentation, State Management, and Validation.
- Step-by-Step Design Approach.
- Principles, patterns, and practices. Using the application types, canonical frame, and cross-cutting concerns as backdrops, the guide provides an overlay of relevant principles, patterns, and practices.
- Technologies and capabilities. The guide provides an overview and description of the Microsoft custom application development platform and the main technologies and capabilities within it.
Contents at a Glance
The full Microsoft Application Architecture Guide is available for free on MSDN in HTML. This is the contents of the guide at a glance:
Chapters
- Chapter 1: What is Software Architecture?
- Chapter 2: Key Principles of Software Architecture
- Chapter 3: Architectural Patterns and Styles
- Chapter 4: A Technique for Architecture and Design
- Chapter 5: Layered Application Guidelines
- Chapter 6: Presentation Layer Guidelines
- Chapter 7: Business Layer Guidelines
- Chapter 8: Data Layer Guidelines
- Chapter 9: Service Layer Guidelines
- Chapter 10: Component Guidelines
- Chapter 11: Designing Presentation Components
- Chapter 12: Designing Business Components
- Chapter 13: Designing Business Entities
- Chapter 14: Designing Workflow Components
- Chapter 15: Designing Data Components
- Chapter 16: Quality Attributes
- Chapter 17: Crosscutting Concerns
- Chapter 18: Communication and Messaging
- Chapter 19: Physical Tiers and Deployment
- Chapter 20: Choosing an Application Type
- Chapter 21: Designing Web Applications
- Chapter 22: Designing Rich Client Applications
- Chapter 23: Designing Rich Internet Applications
- Chapter 24: Designing Mobile Applications
- Chapter 25: Designing Service Applications
- Chapter 26: Designing Hosted and Cloud Services
- Chapter 27: Designing Office Business Applications
- Chapter 28: Designing SharePoint LOB Applications
Appendices
- Appendix A: The Microsoft Application Platform
- Appendix B: Presentation Technology Matrix
- Appendix C: Data Access Technology Matrix
- Appendix D: Integration Technology Matrix
- Appendix E: Workflow Technology Matrix
- Appendix F: patterns & practices Enterprise Library
- Appendix G: patterns & practices Pattern Catalog
The Team
Here is the team that brought you the guide:
- Core Dev Team: J.D. Meier, Alex Homer, David Hill, Jason Taylor, Prashant Bansode, Lonnie Wall, Rob Boucher Jr, Akshay Bogawat
- Test Team - Rohit Sharma, Praveen Rangarajan, Kashinath TR, Vijaya Jankiraman
- Edit Team - Dennis Rea
- External Contributors/Reviewers - Adwait Ullal; Andy Eunson; Brian Sletten; Christian Weyer; David Guimbellot; David Ing; David Weller; Derek Greer; Eduardo Jezierski; Evan Hoff; Gajapathi Kannan; Jeremy D. Miller; John Kordyback; Keith Pleas; Kent Corley; Mark Baker; Paul Ballard; Peter Oehlert; Norman Headlam; Ryan Plant; Sam Gentile; Sidney G Pinney; Ted Neward; Udi Dahan
- Microsoft Contributors / Reviewers - Ade Miller; Amit Chopra; Anna Liu; Anoop Gupta; Bob Brumfield; Brad Abrams; Brian Cawelti; Bhushan Nene; Burley Kawasaki; Carl Perry; Chris Keyser; Chris Tavares; Clint Edmonson; Dan Reagan; David Hill; Denny Dayton; Diego Dagum; Dmitri Martynov; Dmitri Ossipov; Don Smith; Dragos Manolescu; Elisa Flasko; Eric Fleck; Erwin van der Valk; Faisal Mohamood; Francis Cheung; Gary Lewis; Glenn Block; Gregory Leake; Ian Ellison-Taylor; Ilia Fortunov; J.R. Arredondo; John deVadoss; Joseph Hofstader; Koby Avital; Loke Uei Tan; Luke Nyswonger; Manish Prabhu; Meghan Perez; Mehran Nikoo; Michael Puleio; Mike Francis; Mike Walker; Mubarak Elamin; Nick Malik; Nobuyuki Akama; Ofer Ashkenazi; Pablo Castro; Pat Helland; Phil Haack; Rabi Satter; Reed Robison; Rob Tiffany; Ryno Rijnsburger; Scott Hanselman; Seema Ramchandani; Serena Yeoh; Simon Calvert; Srinath Vasireddy; Tom Hollander; Wojtek Kozaczynski
Application Architecture Knowledge Base
The guide was developed in conjunction with our Application Architecture Guide v2.0 Knowledge Base Project. The knowledge base project was used to inform and steer the guide during its development. The Application Architecture Knowledge Base includes a large amount of material that expands on specific topics in the main guide. It also includes draft material from the main guide that is targeted and packaged for more specific audiences, such as the Pocket Guide series.
Key Links at a Glance
Here are the key links at a glance:
Thursday, October 15, 2009
10/GUI: Fascinating Multitouch User Interface Design
If you want to see what the next generation of UI might look like, take a look at this concept.
Wednesday, September 30, 2009
Using Decorator (or Wrapper) Design Patterns to add Validation to an object
Context
In most cases when someone write about the Decorator pattern it is usually related to UI stuff. The most common example is adding “decoration” to a control, for example a scroll bar. But in my humble opinion, this is not the most useful usage of Decorator. The purpose this pattern is:
“Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to sub classing for extending functionality”
Gang of Four
If you think about it, Validation is a responsibility and so it can be added by this pattern. Of course we can add the validation to the class itself or in its base class, but how would you reuse this validation across many unrelated objects and what if you object must derive from another base class?
Solution
The solution is the Decorator pattern. With this pattern we can add new responsibility to an object without changing its internals.
For simplicity purpose we will take a simple sample that anyone can understand but the concept shown here can apply to much more complex object.
Four our sample we will take a bank account. On this account we should be able to to money deposit and withdraw. The class diagram on the right illustrate this design.
Let’s start by defining our IAccount interface
namespace Model { public interface IAccount { string AccountNumber { get; } decimal Balance { get; } bool Active { get; } void Deposit(decimal amount); void Withdraw(decimal amount); void Close(); } }
This simple interface will be the central abstraction of the system. The goal is to never depends on concrete class and this interface in enough to add a lot of functionality around an account.
Now here the interface implementation as an Account:
using System.Diagnostics; namespace Model { [DebuggerDisplay("Account = {_accountNumber}, Balance = {_balance}")] public class Account : IAccount { public string AccountNumber { get; private set; } public decimal Balance { get; private set; } public bool Active { get; set; } internal Account(string accountNumber, decimal balance) { AccountNumber = accountNumber; Balance = balance; Active = true; } public void Deposit(decimal amount) { if (OnBeforeDeposit()) Balance += amount; OnAfterDeposit(); } protected virtual bool OnBeforeDeposit() { return true; } protected virtual void OnAfterDeposit() { } public void Withdraw(decimal amount) { if (OnBeforeWithdraw()) Balance -= amount; OnAfterWithdraw(); } protected virtual bool OnBeforeWithdraw() { return true; } protected virtual void OnAfterWithdraw() { } public void Close() { if (OnBeforeClose()) Active = false; OnAfterClose(); } protected virtual bool OnBeforeClose() { return true; } protected virtual void OnAfterClose() { } } }
If you expand the previous block of code you will see that the implementation of IAccount is only doing business stuff. There is no other responsibility in this class than the one that is meant for. We can clearly see “Template Method” design pattern here. All “OnSomething()” method are protected and any derided class can add implementation around the process. All “Before” method can cancel the process if the return value is false. This allow extension classes to add some specific behaviour.
But one of the main thing missing in this class is “validation”. We will use the decorator pattern to do that. A decorator class is a class thst implement all the member of an abstraction and forward all the calls to an internal instance of a real implementation that abstraction. In our case the abstraction is “IAccount” so we have to make a decorator that implement that interface.
namespace Model.Decorator { public abstract class AccountDecorator : IAccount { private readonly IAccount _account; protected IAccount Account { get { return _account; } } protected AccountDecorator(IAccount account) { _account = account; } public string AccountNumber { get { return Account.AccountNumber; } } public decimal Balance { get { return Account.Balance; } } public bool Active { get { return Account.Active; } } public virtual void Deposit(decimal amount) { Account.Deposit(amount); } public virtual void Withdraw(decimal amount) { Account.Withdraw(amount); } public virtual void Close() { Account.Close(); } } }
As you can see the constructor of the decorator takes an instance of “IAccount”. All method forward their call to that instance. This base class simplifies the process of creating concrete decorator by allowing other decorator to implement some but not all members of the interface.
Now is the time to start implementing our validation class structure. For that purpose we will create a base validation class that will be responsible of applying the validation the IAccount instance.
using System.Collections.Generic; using Model.Decorator; namespace Model.Validator { public abstract class AccountValidatorBase : AccountDecorator { protected abstract IEnumerable<IValidation> GetValidations(decimal amount); protected AccountValidatorBase(IAccount account) : base(account) {} protected void Validate(decimal amount) { foreach (var validation in GetValidations(amount)) if (!validation.IsValid) throw validation.Exception; } } }
This simple base class define a “GetValidations” method that all derived class must override to add a list of validation to perform on method call.
Now to implement the “Deposit” validation we have to create this class:
using System.Collections.Generic; using Model.Validation; namespace Model.Validator { public class AccountDepositValidator : AccountValidatorBase { public AccountDepositValidator(IAccount account) : base(account) {} protected override IEnumerable<IValidation> GetValidations(decimal amount) { return new List<IValidation> { new AmountGreaterThanZeroValidation(amount), new AmountShouldHaveOnlyTwoDecimals(amount), new AccountMustBeActiveValidation(Account), new DepositAmountNotExceedMaxValidation(Account, amount) }; } public override void Deposit(decimal amount) { Validate(amount); Account.Deposit(amount); } } }
This class is responsible for creating all validation instances. The “Deposit” method is overridden to call the base “Validate” method before doing the actual deposit.
To implement those validation we need to define the “IValidation” interface.
using System; namespace Model.Validator { public interface IValidation { bool IsValid { get; } Exception Exception { get; } } }
Here is a sample implementation:
using System; using Model.Validator; namespace Model.Validation { public class AmountGreaterThanZeroValidation : IValidation { public AmountGreaterThanZeroValidation(decimal amount) { Amount = amount; } public decimal Amount { get; set; } public bool IsValid { get { return Amount > 0; } } public Exception Exception { get { return new ArgumentOutOfRangeException("amount", Amount, "Deposit amount should be greater than 0."); } } } }
All other validations used in “AccountDepositValidator” can be described the same way.
The last step is to create an actual “IAccount” that will implement all this stuff. To do that we will need a Bank class. A bank is responsible of creating account. It will also be responsible of decorating it with all necessary decorators.
using System; using System.Collections.Generic; using Model.Logging; using Model.Validator; namespace Model { public static class Bank { static readonly SortedDictionary<string, IAccount> _accounts = new SortedDictionary<string, IAccount>(); private static int _accountSequence = 1; public static IAccount CreateAccount(decimal balance) { string accountNumber = String.Format("A{0:0000}", _accountSequence++); IAccount account = new Account(accountNumber, balance); account = new AccountDepositValidator(account); _accounts[account.AccountNumber] = account; return account; } } }
To illustrate this process in action here is a sequence diagram:
- Call Bank.CreateAccount.
- The Bank instantiate an Account class.
- The Bank create an AccountDepositValidator and wrap Account with it
- The Bank return an instance of IAccount.
- Deposit is called on IAccount which is an instance of AccountDepositValidator
- AccountDepositValidator call Validate
- AccountDepositValidator call GetValidations to retrieve the list of validation to evaluate
- An AmountGreaterThaZeroValidation is created
- IsValid returns true
- AccountDepositValidator call base Deposit method
- Balance value is updated
Next
With all this in place the only thing left to do is to implement all the other validators for all method of “IAccount”.
@ 9/30/2009 09:26:00 PM 7 commentaires
Label: Architecture, C#, Design, OOP
Friday, September 4, 2009
Coder une application d'affaire avec Silverlight (Montreal event)
La Communauté .NET de Montréal organise une journée de formation Silverlight samedi le 24 octobre prochain. Pour plus d'information et pour vous enregistrer, veuillez consulter le site suivant:
Windows 7 Launch Parties!
Be Part of Windows History, Host a Windows 7 Launch Party!
Windows 7 Launch party sign-ups are now open across the world! Chosen hosts will receive a free, signature edition of Windows 7 Ultimate!
Host slots are limited – so sign up early!
Go here to sign up: http://www.houseparty.com/windows7
If you are an MVP and plan to host your own Windows 7 party. Please don't forget to upload your pictures and videos to the MVP Award Program page on Facebook. We would love to see your launch party!
Are you Twitter user? Use #win7meetup when you Tweet about it!
Monday, August 24, 2009
Friday, July 31, 2009
TechDays 2009 Sessions Announced, and Other News
Developer Sessions at TechDays
The sessions for TechDays 2009, Microsoft's cross-Canada conference taking place in seven cities this fall, have been posted on the TechDays site. You can go there to see the full set of sessions, or you can check the table below to look at the sessions for the tracks related to software development.
I'm the lead for the Developing for the Microsoft-Based Platform track and John Bristowe is lead for the Developer Fundamentals and Best Practices track. John and I picked the best developer-focused sessions from this year's TechEd conference and put them into our tracks. We've also chosen speakers for each session in each of TechDays' seven cities, going for local developers wherever possible. TechDays features international conference material and local speakers, right near where you live. We're not just expanding your knowledge, we're stretching your dollar, too!
And now, the developer sessions…
Track: Developing for the Microsoft-Based Platform | Track: Developer Fundamentals and Best Practices |
Learning key skills to develop rich client and web-based applications on the Microsoft-based platform is what this track is all about. In this track you will learn how to develop rich, interactive and interoperable applications for both the client and the web using our newest tools and frameworks. You'll learn how to build software that helps to give your users the best experience possible, whether it's a program running on Windows 7, a website built on ASP.NET MVC or a Silverlight-based rich internet application. You'll also learn how to build services that can deliver data to almost any platform and internet-enabled device. And finally, you'll learn how to build these software and services in ways that are modular and maintainable. | This track is all about taking your skills up a notch while at the same time ensuring effective and efficient interaction with all members of the development team from IT architect, to developer, to tester. You will learn about the importance of Application Lifecycle Management (ALM) and how to leverage the Visual Studio development platform to streamline your efforts. You will learn some best practices from industry professionals while building upon your technical foundation. |
Day One: Front End - User Interface and Experience | Day One: Core Fundamentals and Best Practices |
Day 1, Session 1: | Day 1, Session 1: |
Day 1, Session 2: | Day 1, Session 2: |
Day 1, Session 3: | Day 1, Session 3: |
Day 1, Session 4: | Day 1, Session 4: |
Day Two - Back End: Programming Frameworks and Principles | Day Two - Team System Fundamentals and Best Practices |
Day 2, Session 1: | Day 2, Session 1: |
Day 2, Session 2: | Day 2, Session 2: |
Day 2, Session 3: | Day 2, Session 3: |
Day 2, Session 4: | Day 2, Session 4: |
Free TechNet Plus Subscription for TechDays Attendees
Your admission to TechDays gets you more than just two days' worth of conference and networking. We're also putting together a package of goodies that you can use long after we've turned out the lights at the last TechDays venue.
One such goodie is a full year's subscription to TechNet Plus, the Microsoft IT pro resource that gives you, among other things, full, non-time-limited versions of operating systems, servers and Office System software for evaluation (non-production) use. It also gives you access to pre-release versions, a full technical infromation library, two free tech support calls, and more, It's a US$349 value that you get for free if you attend TechDays.
More Than Just a Conference
In addition to coming to a city near you to hold TechDays, we're planning activities for each city in our tour – things like user group events, academic events, Coffee and Code and more! Watch this blog for announcements for your city.
We also have some surprises in store, and we'll announce them…soon.
Register at the Early Bird Price
You could pay the full price of CDN$599 if you really wanted to. We think that you'd rather save a whole $300 and pay just CDN$299. The early bird price for any of the TechDays cities is available only until 6 weeks before that city's conference, and the Vancouver and Toronto conferences are happening in September. Procrastinate at your peril – register now!
Wednesday, July 29, 2009
Thursday, July 23, 2009
Type-safe INotifyPropertyChanged and derived classes
Some of you who read my previous blog post notice that this technique doesn't allow to raise “PropertyChanged” event from a derived class. This is because you can only call method of “PropertyChangedEventHandler” from the class where it is defined. Anywhere else you can only assign (+=) and unassign (-=) event handler.
One way to work around this is to add a method in your base model class that will forward the call to “PropertyChangedEventHandler”.
Here is a modified copy of the class from my previous post:
public class Model : INotifyPropertyChanged { private string _data; public string Data { get { return _data; } set { if (_data == value) return; _data = value; // Type safe raise from base method RaisePropertyChanged(() => Data); } } protected void RaisePropertyChanged(Expression<Func<object>> expression) { PropertyChanged.Raise(expression); } #region Implementation of INotifyPropertyChanged public event PropertyChangedEventHandler PropertyChanged = null; #endregion }
Now you can define a derived class and use the same method to raise a PropertyChanged event.
public class DerivedModel : Model { private string _moreData; public string MoreData { get { return _moreData; } set { if (_moreData == value) return; _moreData = value; RaisePropertyChanged(() => MoreData); } } }
Now with very little effort you can build a type-safe and bindable data model.
It is also useful to be able to raise many property at once. For example if have calculated properties that depends on others like in this sample class:
public class User : INotifyPropertyChanged { private string _lastName; public string LastName { get { return _lastName; } set { if (_lastName == value) return; _lastName = value; RaisePropertyChanged(()=>LastName, ()=>FullName); } } private string _firstName; public string FirstName { get { return _firstName; } set { if (_firstName == value) return; _firstName = value; RaisePropertyChanged(() => FirstName, () => FullName); } } public string FullName { get { return String.Format("{0} {1}", _firstName, _lastName); } } public void RaisePropertyChanged(params Expression<Func<object>>[] expression) { PropertyChanged.Raise(expression); } #region Implementation of INotifyPropertyChanged public event PropertyChangedEventHandler PropertyChanged = null; #endregion }
Because a change to either “FirstName” or “LastName” should trigger a change to “FullName” you have to raise both changes from both properties. Of course you can call “RaisePropertyChanged” many times but with a simple overload you can do this. All you have to do is add this to your extensions class.
public static void Raise(this PropertyChangedEventHandler handler, params Expression<Func<object>>[] proppertyExpressions) { foreach (var expression in proppertyExpressions) Raise(handler, expression); }
Aside from beeing type safe, this method will give you intellisense support while you type your “RaiePropertyChanged” calls. You still have to type the right property though.
Wednesday, July 22, 2009
How to use INotifyPropertyChanged, the type-safe way (no magic string)
Implementation of the INotifyPropertyChanged interface is quite simple. There is only one event to implement. Take for example the following simple model class:
public class Model : INotifyPropertyChanged { private string _data; public string Data { get { return _data; } set { if (_data == value) return; _data = value; // Type un-safe PropertyChanged raise PropertyChanged(this, new PropertyChangedEventArgs("Data")); } } #region Implementation of INotifyPropertyChanged public event PropertyChangedEventHandler PropertyChanged = null; #endregion }
This is a pretty standard way to implement a bindable property. The problem here is the “Data” string to specify which property changed. If someone change the name of the property without changing the content of the string, the code will compile fine but won’t work. In a big application with may properties it can be hard to detect and find the problem.
The best solution is to rely on the compiler to warn us. But because the property name is a string it can’t. So let’s change that line with a type-safe one.
public class Model : INotifyPropertyChanged { private string _data; public string Data { get { return _data; } set { if (_data == value) return; _data = value; // Type safe PropertyChanged raise PropertyChanged.Raise(() => Data); } } #region Implementation of INotifyPropertyChanged public event PropertyChangedEventHandler PropertyChanged = null; #endregion }
What is the trick? Raise is an extension method that takes a lambda expression to specify the name of the property in a type safe way. The Raise method resolve this expression to extract the name of the property and pass it to the PropertyChanged event.
public static class PropertyChangedExtensions { public static void Raise(this PropertyChangedEventHandler handler, Expression<Func<object>> propertyExpression) { if (handler != null) { // Retreive lambda body var body = propertyExpression.Body as MemberExpression; if (body == null) throw new ArgumentException("'propertyExpression' should be a member expression"); // Extract the right part (after "=>") var vmExpression = body.Expression as ConstantExpression; if (vmExpression == null) throw new ArgumentException("'propertyExpression' body should be a constant expression"); // Create a reference to the calling object to pass it as the sender LambdaExpression vmlambda = Expression.Lambda(vmExpression); Delegate vmFunc = vmlambda.Compile(); object vm = vmFunc.DynamicInvoke(); // Extract the name of the property to raise a change on string propertyName = body.Member.Name; var e = new PropertyChangedEventArgs(propertyName); handler(vm, e); } } }
All you have to do is to put this extension method in your code and the jib is done. Of course at the end a string will be used to raise the PropertyChanged event but because you don’t have to type it, you don’t have to maintain it.
Tuesday, July 21, 2009
How to use INotifyPropertyChanged, the type-safe way (no magic string)
Implementation of the INotifyPropertyChanged interface is quite simple. There is only one event to implement. Take for example the following simple model class:
public class Model : INotifyPropertyChanged { private string _data; public string Data { get { return _data; } set { if (_data == value) return; _data = value; // Type un-safe PropertyChanged raise PropertyChanged(this, new PropertyChangedEventArgs("Data")); } } #region Implementation of INotifyPropertyChanged public event PropertyChangedEventHandler PropertyChanged = null; #endregion }
This is a pretty standard way to implement a bindable property. The problem here is the “Data” string to specify which property changed. If someone change the name of the property without changing the content of the string, the code will compile fine but won’t work. In a big application with may properties it can be hard to detect and find the problem.
The best solution is to rely on the compiler to warn us. But because the property name is a string it can’t. So let’s change that line with a type-safe one.
public class Model : INotifyPropertyChanged { private string _data; public string Data { get { return _data; } set { if (_data == value) return; _data = value; // Type safe PropertyChanged raise PropertyChanged.Raise(() => Data); } } #region Implementation of INotifyPropertyChanged public event PropertyChangedEventHandler PropertyChanged = null; #endregion }
What is the trick? Raise is an extension method that takes a lambda expression to specify the name of the property in a type safe way. The Raise method resolve this expression to extract the name of the property and pass it to the PropertyChanged event.
public static class PropertyChangedExtensions { public static void Raise(this PropertyChangedEventHandler handler, Expression<Func<object>> propertyExpression) { if (handler != null) { // Retreive lambda body var body = propertyExpression.Body as MemberExpression; if (body == null) throw new ArgumentException("'propertyExpression' should be a member expression"); // Extract the right part (after "=>") var vmExpression = body.Expression as ConstantExpression; if (vmExpression == null) throw new ArgumentException("'propertyExpression' body should be a constant expression"); // Create a reference to the calling object to pass it as the sender LambdaExpression vmlambda = Expression.Lambda(vmExpression); Delegate vmFunc = vmlambda.Compile(); object vm = vmFunc.DynamicInvoke(); // Extract the name of the property to raise a change on string propertyName = body.Member.Name; var e = new PropertyChangedEventArgs(propertyName); handler(vm, e); } } }
All you have to do is to put this extension method in your code and the jib is done. Of course at the end a string will be used to raise the PropertyChanged event but because you don’t have to type it, you don’t have to maintain it.
Monday, July 20, 2009
Silverlight MVP Creates PRISM Videos and Interviews!
via The Microsoft MVP Award Program Blog by Jas Dhaliwal on 7/20/09
PRISM is a collection of tools for building maintainable and scalable Silverlight applications. It was created by the Microsoft's Patterns and Practices team, and is a collection of libraries, code, documentation and samples.
Silverlight MVP Erik Mork has created a great suite of resources that can help the community to get started with the technology. Check out the list of video, blog posts and podcasts below for further information!
5 minute introduction to PRISM - 10 Things to Know About Silverlight PRISM. This post covers the essential things that web developer should know about PRISM.
Hyper-Videos - These are screencasts in a rich Silverlight Player. They include code that can be copied and pasted while watching the video. In addition, there is video navigation and deep linking support.
Intro to Silverlight PRISM - Silverlight PRISM Video Testing/Module Catalog/Unity - Modularity in PRISM Video
Regions (including Region Scope, Region Adapter and Region Context) - PRISM Regions Video Commanding (including creating new commands) - Commanding in PRISM Video Eventing - Eventing in PRISM Video
Podcast Interviews - These interviews were recorded with the Patterns and Practices team.
· What is PRISM - What is PRISM Interview
· How Modularity Works in PRISM - PRISM Modularity Interview
· When to use PRISM - When to use PRISM Interview
· How Regions Work in Prism - Regions in PRISM Interview
· View or Presenter First? - View or ViewModel First Interview
· How Commanding Works in PRISM- Commanding in PRISM Interview
· Loosely Coupled Communications in PRISM - Event Aggregator in PRISM Interview
Blog Posts - Helper resources for PRISM
PRISM Overview Post - 10 Things to Know about Silverlight PRISM (overview of all resources) Downloading and Building Prism - Finding and Building PRISM Post
Learning new technologies, who should pay the price?
Sometimes I’m wondering, what am I doing in computer science? I’m good at it, or I think I am, but there always something new to learn.
Ever since the beginning of my career and may be before that I have to learn new things, new concepts, new technologies, new practice to do my job. I’m not complaining, I love to learn. It keeps me motivated, but who should pay the price.
I rarely did the same kind of project twice. Anyway it would be boring. I’m the kind of guy that like to build new things, to boldly go where no one has gone before (Start Trek). But this time I think I took the biggest leap of my career.
In my current project I use many new and emerging technologies, and beside the fact I’m coding in C# it’s all new to me.
Microsoft CRM 4.0
First our whole project is built on top of Microsoft CRM 4.0, it acts as our repository. We chose CRM because it has most of the data structure we need for our project. Hopefully I’m working with Alexandre Leduc who knows all the bells and whistles of MS CRM.
LINQ to CRM
One of the technology we use to connect our application to CRM is Linq to CRM. This is a fairly new project on codeplex, in fact it’s not final yet. There still many Linq command missing from this framework. But because it uses CRM as an IQueryable<T>, it gives us the performance we need.
ADX Studio CRM Metal
Because entities generated by linq to CRM are somewhat hard to manage (all the names are lower case and some of them have custom prefix), we use CRM Metal to generate our plain domain model. CRM Metal annotate all the classes and properties with attributes that helps to find the underlying linq to CRM types. We use those information as mapping when we load a new object in memory.
RegEx
Because we want to be able to bind our UI to our domain model and it doesn’t implement INotifyPropertyChanged we use a find and replace regular expression to change all auto properties to properties with a backing field and a RaisePropertyChanged. At first we used PostShap to do that but it was way too slow to compile and because our data model is so big it was generating OutOfMemoryException every once in a while.
Windows Presentation Framework (WPF)
Just because its the new trend and a little because we want to be able to style our application, we chose to use WPF for our front end application. This is my first real experience with WPF, so I have everything to learn. I have to rethink the way I build an application layout. Expression Blend is an awesome tool when you finally understand how it works.
Composite Application Block for WPF and Silverlight 2.0 (formerly known as Prism)
I merely had the chance to work with the CAB framework with winform in a previous project, so Prism was almost all new stuff for me. Besides all the CAB concepts of shell, modules, views, services, commands, messages, Prism introduce Unit Application Block. Unity is an Inversion Of Control (IOC) container and a Dependency Injection (DI) framework. The basic concept is, the framework will handle the discovery and/or the creation of instance and will give you that instance on demand when you request it by its interface. This saves a lot of code and removes hard dependencies. When you start a new module (class) you only have to declare interfaces arguments to your constructor and Unity will handle you the appropriate instance. It a little overwhelming at first because you look like you loose control of your code. After a while you get used to it.
Who should pay the price?
As you can imagine, learning all that takes time, and the project still has a budget and a timeframe. It’s hard to throw all those costs to the customer. So, I take most of that on my shoulder hoping that someday I will reuse all this knowledge.
Saturday, July 18, 2009
Plenty of Color Resource for Expression
Thinking about a color palette for your new website or application project? I've been using the site Colourlovers.com to get color inspirations. It's a virtual color library where you can find thousands of color palettes, articles on color design, and follow color trends from magazine and websites.
What's more useful about the site is that you can import the color palettes into Expression Design as swatches or add them into Expression Blend as application resources. Let me show you an example:
Summer is in the air and a mixed berry lemonade sounds good. :) I found the follow color palette on the site.
Once you registered as a site user, you can download the palette and import into Expression Design as a Swatch Library (below left).
Or, you can download the XAML file and copy the content into your Silverlight application's App.xaml file (see below). Make sure to insert the the code into the Application.Resource section of your App.xaml. You can see the result in Blend as the one on the right above. Simply just drag and apply brush onto the objects on canvas.
Color is an important element of graphics design. Here's a nice article talks about the Color Basics: Do's and Don'ts. Check out the article and have fun with color in Expression.
Monday, July 13, 2009
Microsoft Office 2010 Web Apps to be Free; Testing Starts Today [Microsoft]
After Microsoft's initial announcement, the forthcoming Google-docs-like Office web apps—"Office Web"—kinda fell off the radar. Today, we get confirmation that the online suite will be free, and that Office 2010 will start semi-private testing today.
With free or cheap alternatives from Google, Zoho, Apple and Adobe, Microsoft didn't really have much a choice when it came to pricing the online suite: it'd either be free, or a failure. Thankfully, the apps, which include Word, PowerPoint, Excel and OneNote, will be available to anyone with a Live account, and judging by the (lone) screenshot above, will aim to compete directly, feature-wise, with other companies' offerings—although hopefully with better handling of complex formatting.
This announcement is paired with news that the actual suite, shown in the gallery above, has hit the "Technical Preview" stage, and that it'll be available for testing to tens of thousands of users, albeit by invitation. (Although for the rest of us, it's already been leaked) There aren't a ton of surprises in the announcements, but PowerPoint video editing, new grou-editing tools, and a bevy of small tweaks and feature-adds can be expected. [Microsoft]
Office 2010 Hits Major Milestone and Enters Technical Preview Microsoft showcases new product capabilities and announces Office Web applications will be available to nearly half a billion people at launch.
NEW ORLEANS, La. - July 13, 2009 - Today, at its Worldwide Partner Conference, Microsoft Corp. announced Office 2010, SharePoint Server 2010, Visio 2010 and Project 2010 have reached the technical preview engineering milestone. Starting today, tens of thousands of people will be invited to test Office and Visio as part of the Technical Preview program. "Office 2010 is the premiere productivity solution across PCs, mobile phones and browsers," said Chris Capossela, senior vice president, Microsoft Business Division. "From broadcast and video editing in PowerPoint, new data visualization capabilities in Excel and co-authoring in Word, we are delivering technology to help people work smarter and faster from any location using any device." Office 2010 and related products will deliver innovative capabilities and provide new levels of flexibility and choice that will help people:
• Work anywhere with Office Web applications—the lightweight, Web browser versions of Word, PowerPoint, Excel and OneNote-that provide access to documents from anywhere and preserve the look and feel of a document regardless of device.
• Better Collaborate with co-authoring in Word, PowerPoint and OneNote, and advanced email management and calendaring capabilities in Outlook, including the option to "ignore" unwanted threads.
• Bring ideas to life with video and picture editing, broadcast capability in PowerPoint, easy document preparation through the new Microsoft Office Backstage view, and new Sparklines in Excel to visualize data and spot trends more quickly;
Microsoft also announced that it is streamlining the number of Office editions from eight to five and enhancing each edition with additional applications and features. The company also announced that Office Web applications will be available in three ways: through Windows Live, where more than 400 million consumers will have access to Office Web applications at no cost; on-premises for the more than 90 million Office annuity customers; and via Microsoft Online Services, where customers will be able to purchase a subscription as part of a hosted offering. Partner Opportunities: Microsoft also is preparing partners for the release of Office 2010 and SharePoint Server 2010 through a number of new and refreshed readiness tools and training programs. These include: the Ignite program for SharePoint, Office and Exchange; Business Productivity Infrastructure Optimization (BPIO) University; Masters and Architect Certification for SharePoint; new Partner Business Productivity Online Services features and distributor model; and, Exchange 2010 Readiness Webcast Series and Demo Showcase. More information on these programs can be found at: http://partner.microsoft.com/businessproductivity
Availability: All Microsoft Worldwide Partner Conference attendees will receive invitations to participate in the Technical Preview program. Microsoft Office 2010 and related products will be available in the first half of 2010. More information about Office 2010 can be found at www.microsoft.com/Office2010 .
Wednesday, July 1, 2009
I’m am an MVP
Tuesday, June 2, 2009
How to implement “lock” with timeout?
Anybody who did any multithreaded application probably used the “lock” keyword. This is actually a good thing.
“lock” is the most optimized way to lock a resource. First let’s take a look at what lock really do. Here is the simple Account class we will use for this post.
using System.Threading; namespace Banking { public class Account { private readonly string _accountNumber; private double _balance; private Account(string accountNumber, double amount) { _accountNumber = accountNumber; Balance = amount; } public string AccountNumber { get { return _accountNumber; } } public double Balance { get { return _balance; } set { _balance = value; } } public static Account OpenNew(string accountNumber, double amount) { return new Account(accountNumber, amount); } public void Deposit(double amount) { Interlocked.Exchange(ref _balance, _balance + amount); } public void Withdraw(double amount) { Interlocked.Exchange(ref _balance, _balance - amount); } public static void Transfer(double amount, Account fromAccount, Account toAccount) { // Bad code here. Potential deadlock. lock (fromAccount) lock (toAccount) { fromAccount.Withdraw(amount); toAccount.Deposit(amount); } } public override string ToString() { return string.Format("{0} (Balance = {1})", _accountNumber, _balance); } } }
Here are some important things to point out about this class:
- The constructor is private to limit the creators of this class.
- The public OpenNew method is the only way to create an instance. This ensure that every Account starts with a name and a balance.
- Deposit and Withdraw methods are thread safe. They both uses Interlocked class which is has low level methods to modify values.
- Transfer is not thread safe even though it uses locks. There is a potential deadlock if two thread transfer funds using the same accounts at the same time.
Most of the time the transfer method will work without any problem but the is a slight chance of deadlock. Of course this is a fairly simple method and in fact we can use another private object field to lock on like in this sample.
private static object _syncLock = new object(); public static void Transfer(double amount, Account fromAccount, Account toAccount) { // Bad code here. Potential deadlock. lock (_syncLock) { fromAccount.Withdraw(amount); toAccount.Deposit(amount); } }
That mean you will need to use that _syncLock object all the time to be consistent, even if you need to lock only one of the two accounts. And because Transfer is a static method we need to make the _syncLock object static too. That mean that any other call to Transfer will have to wait until this call finish. That is a huge performance issue.
What we really need is to be able to lock actual Account objects and recover from any deadlock. The best way to do this is to use timeouts on the locking process. The caller can catch timeouts and handle it properly instead of waiting forever. Here is a better Transfer method.
public static void Transfer(double amount, Account fromAccount, Account toAccount) { bool fromLock = Monitor.TryEnter(fromAccount, 1000); bool toLock = Monitor.TryEnter(toAccount, 1000); try { if (fromLock && toLock) { fromAccount.Withdraw(amount); toAccount.Deposit(amount); } } finally { if (fromLock) Monitor.Exit(fromLock); if (toLock) Monitor.Exit(toLock); } }
This is a lot more code to write. Actually this is not far from what the lock keyword would do. Because if you look at your code with Reflector you will see that lock does translate to Monitor.Enter and Monitor.Exit (your have to look in IL not in C#). So a simple lock statement like this.
lock(obj) { // do somtehing Console.WriteLine("Locked"); }
Would be translated to.
Monitor.Enter(obj); try { // do somtehing Console.WriteLine("Locked"); } finally { Monitor.Exit(obj); }
You won’t see it in C# (with Reflector) but if you look at IL code you will see exactly the same sequence twice.
So to solve our problem, would it be nice to have something like this?
public static void Transfer(double amount, Account fromAccount, Account toAccount) { Safe.Lock(new [] {fromAccount, toAccount}, 1000, () => { fromAccount.Withdraw(amount); toAccount.Deposit(amount); }); }
This look pretty much like the well known lock keyword, isn’t it? Now how can we do this? That’s better. The Safe static call has a Lock static method that take care of everything. The fist argument can be a single object or an array of objects. This allow locking multiple object at once. The Lock method use the Monitor.TryEnter to acquire lock on objects. If this can be done before the timeout occur the Action argument is executed.
Of course this code can and should be surrounded with a try-catch block. here is how to do so.
public static void Transfer(double amount, Account fromAccount, Account toAccount) { var retries = 10; while (retries-- > 0) { try { Safe.Lock(new[] { fromAccount, toAccount }, 1000, () => { fromAccount.Withdraw(amount); toAccount.Deposit(amount); }); break; } catch (TimeoutException e) { if (retries == 0) throw; Thread.Sleep(100); } } }
In this code snippet it will retry at most 10 time to lock toAccount and fromAccount before giving up. Notice that only the TimeoutException is handled, so any other exception will be thrown immediately and stop the process. The break at the end of the try block let us out as soon as it works.
This is a good timeout pattern and easy to implement in your own code. Give it a try and let me know if it works.
Here is the full code for the Safe class.
using System; using System.Linq; using System.Threading; namespace MultithreadHelper { public class Safe : IDisposable { private readonly object[] _padlocks; private readonly bool[] _securedFlags; private Safe(object padlock, int milliSecondTimeout) { _padlocks = new[] {padlock}; _securedFlags = new[] {Monitor.TryEnter(padlock, milliSecondTimeout)}; } private Safe(object[] padlocks, int milliSecondTimeout) { _padlocks = padlocks; _securedFlags = new bool[_padlocks.Length]; for (int i = 0; i < _padlocks.Length; i++) _securedFlags[i] = Monitor.TryEnter(padlocks[i], milliSecondTimeout); } public bool Secured { get { return _securedFlags.All(s => s); } } public static void Lock(object[] padlocks, int millisecondTimeout, Action codeToRun) { using (var bolt = new Safe(padlocks, millisecondTimeout)) if (bolt.Secured) codeToRun(); else throw new TimeoutException(string.Format("Safe.Lock wasn't able to acquire a lock in {0}ms", millisecondTimeout)); } public static void Lock(object padlock, int millisecondTimeout, Action codeToRun) { using (var bolt = new Safe(padlock, millisecondTimeout)) if (bolt.Secured) codeToRun(); else throw new TimeoutException(string.Format("Safe.Lock wasn't able to acquire a lock in {0}ms", millisecondTimeout)); } #region Implementation of IDisposable public void Dispose() { for (int i = 0; i < _securedFlags.Length; i++) if (_securedFlags[i]) { Monitor.Exit(_padlocks[i]); _securedFlags[i] = false; } } #endregion } }
@ 6/02/2009 09:15:00 PM 7 commentaires
Label: C#, Parallel Computing, Threading, Tip
Starting a new user group in Montreal area
Maxime Rouiller and I are starting a new user group in the Montreal area.
It’s called Alt.Net Montreal.
Our goal with this user group is to raise the level of expertise of everyone interested. We already did a Coding Dojo couple of weeks ago and it went well.
We need your input to plan the future. Get involve and together we will build something cool.
All suggestions are welcomed.
Monday, June 1, 2009
Code Camp 2009 Montreal, a real Success
Code camp 2009 at Montreal was a real success.
There was about 300 people attending and 24 sessions available.
My session on Threading, UI and Data Model, was more than full. There was people standing in the back of the room. I had a lot present but I think I did it well, I hope.
For those of you who were there (and those who were not) you can find all the material on my web site (here).
Thursday, May 21, 2009
Parallel Programming with .NET : Samples for Parallel Programming with the .NET Framework 4
Now that .NET Framework 4 is out, we start seeing new samples.
Parallel Programming with .NET : Samples for Parallel Programming with the .NET Framework 4
Monday, May 18, 2009
Visual Studio 2010 beta 1 is available
Finally Visual Studio 2010 Beta 1 is available. I was waiting for that release for so long. I’m eager to test my Parallel Extensions demo on it.
http://msdn.microsoft.com/en-ca/subscriptions/downloads/default.aspx?pv=18:370
Stay tuned I will tell you how it goes.
Wednesday, May 13, 2009
How to test your multi-threaded code (part 3 of 3)?
In the last post we learned how to find and fix a simple multi-thread problem. Now we will see a more complex scenario and see how CHESS wil find the solution.
To do that we will add a ne method to our Account type.
public static void Transfer(double amount, Account fromAccount, Account toAccount) { lock (fromAccount) { lock(toAccount) { fromAccount.Withdraw(amount); toAccount.Deposit(amount); } } }
Because we want to be sure that the transfer works we lock both the “from” and the “to” account.
Now we can easily wrtie this test to see that this is working fine in signle threaded scenario.
[TestMethod] public void TransferTest() { Account a1 = Account.OpenNew(10000); Account a2 = Account.OpenNew(10000); Account.Transfer(100, a1, a2); Account.Transfer(100, a2, a1); Assert.AreEqual(10000, a1.Balance); Assert.AreEqual(10000, a2.Balance); }
As we did before we will convert this single-thread method to a multi-thread one.
[TestMethod] [HostType("Chess")] public void TransferMultiThreadTest() { Account a1 = Account.OpenNew(10000); Account a2 = Account.OpenNew(10000); Thread thread =
new Thread(o => Account.Transfer(100, ((Account[]) o)[0], ((Account[]) o)[1])); thread.Start(new[] {a1, a2}); Account.Transfer(100, a2, a1); thread.Join(); Assert.AreEqual(10000, a1.Balance); Assert.AreEqual(10000, a2.Balance); }
Now if we run this CHESS will detect a deadlock scenario. If you’ve done some SQL queries you know you should always try to lock all your resources always in the same order. But why doesn’t it working here. We have only one method that lock resources they should be locked in the same order every time, and that’s true. The deadlock occurs because in some cases a thread start to lock the fromAccount (or maybe the toAccount too) and get interrupt by another thread trying to do the same. Then both thread are waiting for each other to complete. Databases engine use timeouts to get out of these situation, but the lock keyword doesn’t support timeout, eventough it uses Monitor.Enter which support it. In another post I will show you how to build your own lock implementation that support timeout, but now we need to find a way to make our code thread safe.
We have to go back to our account class and do some changes.
public static object _locObject = new object(); public static void Transfer(double amount, Account fromAccount, Account toAccount) { lock (_locObject) { fromAccount.Withdraw(amount); toAccount.Deposit(amount); } }
We have to create a static lock object we can use to lock on. Because we are doing the lock in one signle operation our test will now run without any problem.
This is only a small overview of what CHESS can do.
Monday, May 11, 2009
How to test your multi-threaded code (part 2 of 3)?
Previously we saw how to build a test to find a multi-thread bug our your code. Now we will look at how to reproduce debug and fix it.
Remember our bank account class:
public class Account { public double Balance { get; set; } private Account(double amount) { Balance = amount; } public static Account OpenNew(double amount) { return new Account(amount); } public void Deposit(double amount) { double tempAmount = Balance; // potential problem lock (this) { Balance = tempAmount + amount; } } public void Withdraw(double amount) { double tempAmount = Balance; // potential problem lock (this) { Balance = tempAmount - amount; } } }
And our test:
[TestMethod()] [HostType("Chess")] public void BalanceMutiThreadTest() { Account account = Account.OpenNew(10000); Thread thread = new Thread(a => ((Account) a).Withdraw(100)); thread.Start(account); account.Deposit(100); thread.Join(); Assert.AreEqual(10000, account.Balance); }
Now if we look carefully at the test result detail, there is an explanation on how to reproduce this particular schedule. All you have to do is to copy/paste the code provided just before your test method call.
[TestMethod()] [HostType("Chess")] [TestProperty("ChessMode", "Repro")] [TestProperty("ChessBreak", "BeforePreemption")] #region ChessScheduleString (not human readable) [TestProperty("ChessScheduleString", @"bpilaiaaaaaaaaaaaeaaonlnahgabmejjgcfcgcpgnmkhlhpekpfeknhoahekbaiiagabdcenijaeabaommbiimnogjcombngjehcdcjklckibmkgffggffnggbgeammonjnlmphnohloplnphnohloplnphlkdljneochphnpppdpfmgggeabgmpgmoeknkmjjocbiakkmibpdphohmbpdpcchomnfpodnhpidfpappfpfhhpponplpkgpmdelpppbgpkplkpoflfmbopdpkgdppbppfpephpocllfpedhppkopjkppjlohpppohpaaldcaoojfhfaaaaaa")] #endregion public void BalanceMutiThreadTest() { Account account = Account.OpenNew(10000); Thread thread = new Thread(a => ((Account) a).Withdraw(100)); thread.Start(account); account.Deposit(100); thread.Join(); Assert.AreEqual(10000, account.Balance); }
(your code may be different)
With that code in place if you run your test again (without the debugger) you will see that only one schedule was evaluated and you got the same result as the previous test. From there, as a tester, you job is done. You check in the code and hand it to the development team. If you are a member of a small team, as I usually am, you may be the tester and the developer so you’ll have to debug the code yourself.
Now run this test again but this time with the debugger. The execution should stop just before one of the lock statement. If you step once you will be able to inspect tempAmount and Balance values and see the problem. Between the line where the debugger stop and the previous line another thread changed the Balance value. Now you can see the don’t match.
Of course in this case the solution is easy, we just have to put the tempAmount assignation inside of the lock block but in the next post you will see a case where the solution is not so obvious.
Tuesday, May 5, 2009
How to test your multi-threaded code (part 1 of 3)?
CHESS is the answer. At least this is what we have best right now.
In multi-threaded application, bug are hard to almost impossible to find. For the last years the only true way to detect threading problems was to run load test until the system crash. Once it does, every once in thousands of iterations, the tools to reproduce and debug the problem were inexistent.
The RiSE (Research in Software Engineering) team at Microsoft have been working for a long time on a product called CHESS. When run with CHESS, you unit tests will try every possible combination of thread interleave to find a case where you application crash or worst doesn’t give you the result you expect.
Here is a simple demo to show you the power of CHESS. Let’s start with a banking account management system.
public class Account { public double Balance { get; set; } private Account(double amount) { Balance = amount; } public static Account OpenNew(double amount) { return new Account(amount); } public void Deposit(double amount) { double tempAmount = Balance; // potential problem lock (this) { Balance = tempAmount + amount; } } public void Withdraw(double amount) { double tempAmount = Balance; // potential problem lock(this) { Balance = tempAmount - amount; } } }
Of course I voluntarily introduce “potential problems” to show how CHESS will get them. With that class you can write this test:
[TestMethod()] public void BalanceTest() { Account account = Account.OpenNew(10000); account.Withdraw(100); account.Deposit(100); Assert.AreEqual(10000, account.Balance); }
This will always run fine as it is single threaded. Now what if we change it a little to make it multi-threaded:
[TestMethod()] public void BalanceMutiThreadTest() { Account account = Account.OpenNew(10000); Thread thread = new Thread(a => ((Account) a).Withdraw(100)); thread.Start(account); account.Deposit(100); thread.Join(); Assert.AreEqual(10000, account.Balance); }
As you can see here we put the withdraw part in a new thread. But even then we can run this test again and again without any problem. You can put it in a loop if you want and never being able to make it return an invalid balance.
Once you have CHESS installed on your system the only thing you have to do is to add a HostType attribute to your method.
[TestMethod()] [HostType("Chess")] public void BalanceMutiThreadTest() { Account account = Account.OpenNew(10000); Thread thread = new Thread(a => ((Account) a).Withdraw(100)); thread.Start(account); account.Deposit(100); thread.Join(); Assert.AreEqual(10000, account.Balance); }
Now when you run this test you should get something like:
Assert.AreEqual failed. Expected:<10000>. Actual:<10100>.
You should also have noticed that it took a little longer to run the test. This is because the CHESS host scans your code to build an execution schedule for every possible thread interleave that CHESS can detect. If you double click on the test result you will see how many schedules that were tried before finding the bug, in my case it is 3.
Next time we will see how to reproduce and debug that code.
Friday, April 24, 2009
Parallel Extension Talk at Vermont .NET User Group
I want to thank Julie Lerman for letting me talk about Parallel Extensions at the Vermont .NET User Group.
The power point slides are available as well as the code samples.