Archives for : MVVM

Live Filter Design Pattern in XAML

GetTheCode

I decided I should start titling my posts with XAML instead of WPF as they are applicable regardless of whether you are developing in Windows 7 with WPF or Windows 8. I’m going to take the BreadCrumb design pattern sample and extend it to include the Live Filter design pattern.

The premise behind the Live Filter design pattern is pretty simple, show the user everything and then allow them to filter the results, immediately showing how the filter affects the results. As noted in the BreadCrumb post dense trees can easily become overwhelming to users. Providing a simple, easy to use live filter makes the experience significantly better.LiveFilter

In the above image you can see there we have a search text box with two filter parameters. As the user types into the search box the results are immediately filtered.

<Grid Grid.Row="0" Grid.ColumnSpan="3" Margin="5">
    <xctk:WatermarkTextBox Margin="2" Watermark="Search" Text="{Binding SearchValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
    <Button Margin="5 0 5 0" Width="16" Height="16" HorizontalAlignment="Right" FontFamily="Segoe UI Symbol" Opacity=".75" ToolTip="Clear" Command="{Binding ClearCommand}">
        <TextBlock Margin="0 -3.5 0 0" Foreground="#FF63A3B2">👽</TextBlock>
    </Button>
</Grid>
<StackPanel Grid.Row="1" Grid.ColumnSpan="3" Margin="5" Orientation="Horizontal">
    <CheckBox Margin="5" IsChecked="{Binding SearchProperty2, Mode=TwoWay}" Content="Include Property 2 In Search" />
    <CheckBox Margin="5" IsChecked="{Binding SearchProperty3, Mode=TwoWay}" Content="Include Property 3 In Search" />
</StackPanel>

Above is the XAML for the search controls. Most of it is standard MVVM binding. The problem with standard MVVM binding is that for textbox it only updates the underlying view model property on lost focus. That doesn’t help us as we want to update the results in real-time. To fix this the UpdateSourceTrigger is set to PropertyChanged. This way as soon as the user types a letter the property is changed and we can perform a search. (I’m actually using the nuget package for the Extended WPF Toolkit to provide a watermark textbox but it works like a regular textbox).

<TreeView Grid.Row="2" Grid.RowSpan="2" Margin="5" 
        ItemsSource="{Binding ChildNodes}"
        VirtualizingStackPanel.IsVirtualizing="True"
        VirtualizingStackPanel.VirtualizationMode="Recycling"
        SelectedItemChanged="TreeView_SelectedItemChanged">
    <TreeView.ItemContainerStyle>
        <Style TargetType="{x:Type TreeViewItem}">
            <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
            <Setter Property="Visibility" Value="{Binding Visibility, Mode=TwoWay}" />
        </Style>
    </TreeView.ItemContainerStyle>
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding Children}">
            <StackPanel>
                <TextBlock Text="{Binding Property1}" FontSize="18" />
            </StackPanel>
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

The first important part is the TreeViewItemContainerStyle. The nodes implement the properties IsExpanded and Visibility. This is extremely important. We don’t want to have to deal with the ItemContainerGenerator. This can be a major pain the rear and will make the code extremely sluggish. If we’re going to go with binding the nodes in the tree let’s take full advantage of it. The other important part is setting up the VirtualizingStackPanel values. The search is really rather trivial and usually works extremely fast. The slow part is updating the UI. We leave that to the masters at Microsoft by binding everything and letting them figure out how to render it. But we can help things out a bit. By setting up the VirtualizingStackPanel the control doesn’t have to render all the children in the tree. Now use this with some caution. Because the nodes will only be updated as the user drags the scroll bar you can get some choppy and sluggish operations as the control updates.

string searchValue;
public string SearchValue
{
    get { return searchValue; }
    set
    {
        if (SetProperty(ref searchValue, value))
        {
            PerformSearch();
        }
    }
}

bool searchProperty2 = false;
public bool SearchProperty2
{
    get { return searchProperty2; }
    set 
    {
        if (SetProperty(ref searchProperty2, value))
        {
            PerformSearch();
        }
    }
}

bool searchProperty3 = false;
public bool SearchProperty3
{
    get { return searchProperty3; }
    set 
    { 
        if(SetProperty(ref searchProperty3, value))
        {
            PerformSearch();
        }
    }
}

These are the properties in the view model. We’re using BindableBase from Prism for the view model. Thus SetProperty returns a true if there was a change. We need to minimize extraneous calls to PerformSearch as much as possible.

private static object lockObj = new object();
private CancellationTokenSource CancellationTokenSource { get; set; }
private void PerformSearch()
{
    //if we're doing a search then we probably have some new search term
    clearCommand.RaiseCanExecuteChanged();

    lock (lockObj)
    {
        if (CancellationTokenSource != null)
            CancellationTokenSource.Cancel();

        CancellationTokenSource = new CancellationTokenSource();

        resultCount = 0;
    }

    Task.Run(() =>
    {
        DateTime now = DateTime.Now;
        try
        {
            if (string.IsNullOrEmpty(SearchValue))
            {
                ClearAllNodes(ChildNodes, Visibility.Visible, CancellationTokenSource.Token);
                return;
            }
            else
            {
                ClearAllNodes(ChildNodes, Visibility.Collapsed, CancellationTokenSource.Token);
            }

            var options = new ParallelOptions { CancellationToken = CancellationTokenSource.Token };
            try
            {
                Parallel.ForEach(ChildNodes, options, (childNode) =>
                {
                    PerformSearch(childNode, options);
                });
            }
            catch (OperationCanceledException)
            {
                //Noop
            }
        }
        finally
        {
            LastSearchTookInMilliseconds = (DateTime.Now - now).Milliseconds;
            OnPropertyChanged(() => ResultCount);
        }
    }, CancellationTokenSource.Token);
}

private void PerformSearch(RandomValueNode childNode, ParallelOptions options)
{
    if (options.CancellationToken.IsCancellationRequested)
        return;

    if (childNode.Property1.StartsWith(SearchValue) ||
        (SearchProperty2 && childNode.Property2.StartsWith(SearchValue)) ||
        (SearchProperty3 && childNode.Property3.StartsWith(SearchValue)))
    {
        Interlocked.Increment(ref resultCount);
        childNode.IsExpanded = true;
        childNode.Visibility = Visibility.Visible;
    }
    foreach (RandomValueNode node in childNode.Children)
    {
        if (options.CancellationToken.IsCancellationRequested)
            break;

        PerformSearch(node, options);
    }
}

And finally we do the search. To make this as responsive as possible we need to cancel the search each time as quickly as possible. Thus I’m using a CancellationToken in the Task.Run and the Parallel.ForEach to do the search. Remember that it is only effective to spin off threads from the thread pool if you can give them enough work. In my case there will only be ten nodes but I give each of those plenty to do. I’m passing the options into the PerformSearch so that we kill the search as quick as possible. As the code recurses I want to kill everything. It may seem like overkill to check for options.CancellationToken.IsCancellationRequested at the top of the method and in the foreach, and it may very well be.

So this pattern is pretty straightforward, simply update live results as the user changes the filter parameters. The key here is taking into account the result set size and to stop any existing search quickly, really try and take advantage of all that the TPL provides. As you can see in the image at the top I can iterate over 700,000 nodes pretty quickly and the UI is still pretty responsive. Of course that is really more because of the Task.Run and using VirtualizingStackPanel.

There is, of course, another way to do this. If you find that things are moving much too sluggish the other alternative is to show a minimal amount of results (like when doing a Google search and it begins to suggest terms). Then in the background have a thread that starts to update the results.

I would encourage you to get the code from the “GET THE CODE” button at the top.

Thanks for reading,
Brian

Upgrading to Prism 5.0 – BindableBase

I recently upgraded my TPL Samples solution to the latest Prism libraries. I’ve removed the references to the “lib” directory and added Prism as a nuget package. The first thing you’ll notice is that NotificationObject has been deprecated and replaced with Microsoft.Practices.Prism.Mvvm.BindableBase. This makes things really nice as we no longer have such horrible boilerplate code.

What used to be

private string currentState;
public string CurrentState
{
	get { return this.currentState; }
	set
	{
		if (this.currentState != value)
		{
			this.currentState = value;
			this.RaisePropertyChanged(() => this.CurrentState);
		}
	}
}

Now looks like:

private string currentState;
public string CurrentState
{
	get { return this.currentState; }
	set { SetProperty(ref this.currentState, value); }
}

You can see how much cleaner this code is. The SetProperty method in BindableBase will take care of firing any RaisePropertyChanged events for you as well as take care of any needed validation. Check out Upgrading from Prism Library 4.1, which is Microsoft’s guide on upgrading.

Thanks,
Brian

 

Update 05/15/14:

Well, after using this I’ve discovered validation still has to be implemented manually.  I’ll do a future post regarding this.

Brian

So you don’t need to know software design patterns. But, as I hope got across in my post, knowing and understanding patterns can only benefit you. I wanted to put together a real-life example of some of the instances where I’ve used patterns, even if the use of the patterns was unintentional. Hopefully you will get some use out of them.

I had a requirement where I had to track a list of files and needed to be able to save this list. But the list needed to be able to not only have a list of files but needed to support a list of lists. The use case was that the user could define a list of files say, “My files from client A.” The user could then put together a list of lists defined as, “My clients from the east coast” which would be comprised of lists from any clients on the east coast.

Of course this defines the composite pattern. The composite pattern is just an object that contains zero or more of that object. The two most obvious classes in .NET that use this are TreeViewItem and MenuItem. A MenuItem contains it’s own content as a MenuItem but also contains children MenuItems. In my case my class, “FileGroupModel” has a list of files (think of that list as the content of the class) as well as a list of FileGroupModels, which is exactly what the composite design pattern is.

Now to facilitate this I obviously need to save out the FileGroupModel, which is the memento pattern. As you’ll see in the code I went with a DataContract to save out the data.

using CompositeMementoSample.Infrastructure;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;

namespace CompositeMementoSample.Models
{
    [DataContract(IsReference = true)]
    public class FileGroupModel : DomainObject
    {
        public virtual string OpenFileDialogFilter 
        {
            get { return "Files & Groups (*.*)|*.*|File Groups (*.fxml)|*.fxml"; }
        }
        public virtual string SerializedExtension 
        {
            get { return ".fxml"; }
        }

        [DataMember]
        private string name;
        public string Name
        {
            get { return name; }
            set
            {
                if (this.name != value)
                {
                    this.ValidateProperty("Name", value);
                    this.name = value;
                    this.RaisePropertyChanged("Name");
                }
            }
        }

        [DataMember]
        private ObservableCollection<FileInfo> files;
        public ObservableCollection<FileInfo> Files
        {
            get
            {
                return files;
            }
        }

        [DataMember]
        private ObservableCollection<FileGroupModel> groups;
        public ObservableCollection<FileGroupModel> Groups
        {
            get
            {
                return groups;
            }
        }

        public ReadOnlyCollection<object> CompositeList
        {
            get
            {
                List<object> allItems = new List<object>();
                allItems.AddRange(files);
                allItems.AddRange(groups);
                return new ReadOnlyCollection<object>(allItems);
            }
        }

        public FileGroupModel()
        {
            files = new ObservableCollection<FileInfo>();
            files.CollectionChanged += child_CollectionChanged;
            groups = new ObservableCollection<FileGroupModel>();
            groups.CollectionChanged += child_CollectionChanged;
        }

        void child_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            this.RaisePropertyChanged("CompositeList");
        }

        public void WriteToFile(string Path)
        {
            using (MemoryStream memStm = new MemoryStream())
            using (StreamWriter outfile = new StreamWriter(Path))
            {
                DataContractSerializer ser = new DataContractSerializer(typeof(FileGroupModel));
                ser.WriteObject(memStm, this);
                memStm.Seek(0, SeekOrigin.Begin);
                string result = new StreamReader(memStm).ReadToEnd();
                outfile.Write(result);
            }
        }

        public static FileGroupModel ReadFromFile(string Path)
        {
            string contents = System.IO.File.ReadAllText(Path);
            using (Stream stream = new MemoryStream())
            {
                byte[] data = System.Text.Encoding.UTF8.GetBytes(contents);
                stream.Write(data, 0, data.Length);
                stream.Position = 0;
                DataContractSerializer deserializer = new DataContractSerializer(typeof(FileGroupModel));
                object o = deserializer.ReadObject(stream);
                return o as FileGroupModel;
            }
        }

        public override string ToString()
        {
            return Name;
        }
    }
}

To start with, FileGroupModel extends DomainObject which in turn implements INotifyPropertyChanged and INotifyDataErrorInfo. This is done so that the model can integrate into MVVM. DomainObject can be found in my series on MVVM. So the MVVM stuff out of the way, we can get on to the composite design pattern.

Implementing Composite

Looking at line 42 you can see the observable collection that contains our FileInfos. At line 52 you can see the observable collection that contains our FileGroupModels, which makes this the composite pattern.  That’s it.  The composite pattern is just about implementing tree structure data.

CompositeMementoBut we need to use this in MVVM and we can only to bind an ItemsSource to one list. That is the purpose of the CompositeList. By hooking into the CollectionChanged event of the two observable collections, anytime files or file group models are added to either list we can raise a property changed event so the view way down the link that gets hooked up to the model via the view model, can get notified of the change to the collection.  My use of naming the combined list “CompositeList” is a bit unfortunate as I obviously mean that to indicate a combined list and not anything that really has to do with the composite pattern.

Implementing Memento

The last requirement is to be able to save out the state of the object (i.e. the memento design pattern). In .NET, arguably, the two easiest ways to write out an object is BinaryFormatter and DataContract. I tend to only use the binary formatter if there is proprietary data that needs to be stored. When that’s the case I use not only the BinaryFormater but I use it with a CryptoStream to ensure the security of the data. Most of the time, however, I try to use a DataContractSerializer. It’s a bit more in the set-up, having to define the DataContract and DataMember attributes but on the whole everything seems a bit cleaner. That way, if I need to, I can read the XML directly and see what’s going on with the data.

Now the tough part is that if you are going to use multiple classes that extend from a base class then you have to violate the Open-Closed principle. In my use of the above class I actually extend FileGroupModel (which is an abstract in my production code) to limit the types of files that are embedded. The problem with this approach is that you have to define a KnownType attribute in the base class so when you deserialize the object the DataContractSerializer knows what to do with it. This means that every time you add a class that extends the base class you have to add a KnownType for that class in the base. See? An obvious violation of the OCP but definitely a situation where we can ignore the rules on the paint can.

Next week I’ll follow up this post with an MVVM sample that is a bit closer to how I actually use it. I’ll show a sample extending FileGroupModel so you can get a better idea of using DataContractSerializer, but this also leads into using the command design pattern.

Thanks,
Brian

Binding a Dependency Property of a View to its ViewModel

UPDATE 07/30/2014:
Please be sure to check out the second part to this at Binding a Dependency Property of a View to its ViewModel, part Deux which contains a working sample solution of the code here.

I like MVVM in concept and I had prepared a long, off-topic rant about MVVM because of a bit of trouble I’m having with it at the moment.  I deleted it, however.  Maybe I’ll make it an on-topic post at some point in the future.  Regardless, one of the issues I had was I needed to make a user control that could not only be the primary control of a view but I needed it to be a child control of another view.  There are a lot of complex operations that the view model controls in terms of handling states and progress bars.  It made sense, therefore, when I needed almost the exact same operations but with four different classes that inherit from the same model to use the same view.

To do this I needed a way to define a “ViewMode” of the user control.  For the default view where it would be the full version of the control the mode would be “Full” and for where I was using it as a child control the mode would be “Compact”.    Given that I think one of the things we should strive for is re-use it seemed like this should be an easy problem.  After some googling around though the general consensus seemed to be that you should just incorporate this into your new view model.  This just seems stupid to me.

Not about incorporating it into the view model.  That much is obvious but that there wasn’t some easy, obvious solution on how to bind a dependency property to a property in the view model.  Fortunately my StackOverflow foo seemed to be working with me and I found the right answer.

You have to manually bind your dependency property to the property on your view model.  It should have been obvious and I’m not sure why I hit on so many wrong answers but here is my solution:

Add the dependency property to MyView that will bind to the view model

public ViewMode ViewMode
{
	get { return (ViewMode)GetValue(ViewModeProperty); }
	set { SetValue(ViewModeProperty, value); }
}

public static readonly DependencyProperty ViewModeProperty =
	DependencyProperty.Register("ViewMode", typeof(ViewMode), typeof(MyView), new PropertyMetadata(ViewMode.Full));

I’ve defined an enum “ViewMode” that has two values, “Full” and “Compact” and I utilize it here.

Then in the ctor of MyView I have

public MyView()
{
	InitializeComponent();

	//http://stackoverflow.com/questions/15132538/twoway-bind-views-dependencyproperty-to-viewmodels-property
	string propertyInViewModel = "ViewMode";
	var bindingViewMode = new Binding(propertyInViewModel) { Mode = BindingMode.TwoWay };
	this.SetBinding(ViewModeProperty, bindingViewMode);
}

This manually sets the binding to a property “ViewMode” that is in my view model. So “ViewMode” exists in both the view and the view model and the manual binding will keep everything in sync.

In my XAML where I use the control as a stand-alone view the XAML looks like

<views:MyView Grid.Row="1" Margin="50" />

and in my XAML where I use the control as a child control the XAML looks like

<views:MyView Grid.Row="0" Grid.Column="0" ViewMode="Compact" />

MMVVVMVMI have also added some converters to help that bind the visibility of controls to the “ViewMode” of the view model. Now I have to point out that what I need to show and/or hide based on the ViewMode was fairly minimalistic. It might make more sense to have different control but in my case it made more sense to use the same control.

This is great and allows us to customize the view based on the ViewMode, but it doesn’t keep MyParentViewModel of the parent control in sync with MyViewModel of the child control when it’s being used as a child control. To do this we need to add another dependency property in MyView and bind it like we did the ViewMode. Then in MyParentView we have to bind that property to the property of MyParentViewModel in XAML.  The kind of crappy part is there is some manual work you have to do to make this work right.  Not only that but the binding works out to be fairly ugly.

The view model of “MyViewModel” looks like:

class MyViewModel
	ViewMode ViewMode
	ObjectGroup ActiveObject

The view model of “MyParentViewModel” looks like:

class MyParentViewModel
	ObjectGroup ActiveObjectOne
	ObjectGroup ActiveObjectTwo
	ObjectGroup ActiveObjectThree
	ObjectGroup ActiveObjectFour

In “MyView” I add the following dependency property:

public ObjectGroup ActiveObject
{
	get { return (ObjectGroup)GetValue(ActiveObjectProperty); }
	set { SetValue(ActiveObject, value); }
}

public static readonly DependencyProperty ActiveObjectProperty =
	DependencyProperty.Register("ActiveObject", typeof(ObjectGroup), typeof(MyView), new FrameworkPropertyMetadata(null, OnActiveObjectChanged));

private static void OnActiveObjectChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
	((MyViewModel)((MyView)d).DataContext).ActiveObject = (ObjectGroup)e.NewValue;
}

which is incredibly ugly. The problem is that when I do the binding on the dependency it directly calls SetValue and ignores my setter. As such I have to set things up with the property changed call-back to make everything tie together correctly.

Unfortunately I still need to add the manual binding to my view

propertyInViewModel = "ActiveObjectGroup";
var bindingActiveObjectGroup = new Binding(propertyInViewModel) { Mode = BindingMode.TwoWay };
this.SetBinding(ActiveObjectGroupProperty, bindingActiveObjectGroup);

Okay, so now everything works correctly right? Nope. The problem is that the binding on MyView sees the local data context, not the binding I want to give the control from MyParentView. As such I need to play with the binding to make sure we’re all on the same page.

The XAML basically ends up looking like

<UserControl x:Class="MyParentView">
	<UserControl.DataContext>
		<viewModels:MyParentViewModel />
	</UserControl.DataContext>
	<Grid>
		<Grid.RowDefinitions>
			<RowDefinition />
			<RowDefinition />
			<RowDefinition />
			<RowDefinition />
    		</Grid.RowDefinitions>
		<views:MyView Grid.Row="0"
				 ViewMode="Compact" 
				 ActiveObject="{Binding DataContext.ActiveObjectOne, Mode=TwoWay, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}" />
		<views:MyView Grid.Row="1"
				 ViewMode="Compact" 
				 ActiveObject="{Binding DataContext.ActiveObjectTwo, Mode=TwoWay, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}" />
		<views:MyView Grid.Row="2"
				 ViewMode="Compact" 
				 ActiveObject="{Binding DataContext.ActiveObjectThree, Mode=TwoWay, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}" />
		<views:MyView Grid.Row="3"
				 ViewMode="Compact" 
				 ActiveObject="{Binding DataContext.ActiveObjectFour, Mode=TwoWay, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}" />
	</Grid>
</UserControl>

MMVVVMVM2What we’re doing here is changing the default “ActiveObject” in the child control from the one created by its view model to the one created by the parent view model. This way everything is in sync due to the bindings we created in the constructor of “MyView”.

When I bind like I do above the ObjectGroup instances from MyParentViewModel end up being the same as the instance of ObjectGroup in the MyViewModel.

The cool thing about all this is that I can create a new instance of MyParentViewModel as needed and it will set everything up as it should.

And that’s it. Maybe this is one of those answers that is so obvious no one felt the need to write about it. Or maybe everyone’s found the same answer I did. Or maybe this is the wrong approach. After all, it’s not very “MVVM-like”, having to manually create the bindings and then having to manually set the ActiveObject in the dependency property. If you know of a better way to do this let me know.

Thanks,
Brian

The Task Parallel Library Sampler – Part 14: Wrap-up / Future posts

This has been a fun journey and hopefully you’ve learned a bit about MVVM and the TPL. I do have plans for future posts in this series that will center around the TPL.Dataflow namespace. It’s an area of the TPL I don’t seem written about a lot and I think there are probably a few posts that would benefit you.

My next series of posts, however, is on the SOLID principles of good object-oriented programming and design. Often when it comes to concepts like design patterns and MVVM we can’t see the forest from the trees and we get lost in the concepts. The awesome thing about SOLID is that it is so straight-forward that all of us should have a thorough understanding of it.

After SOLID, I have a series planned on design patterns. I won’t cover all the design patterns but will hit on quite a few of them. I also have a post planned on the patterns you don’t really care about if you apply fundamental .net development concepts and practices as the patterns are incorporated into those practices. This will relate to patterns like lazy initialization, object/thread pool, factory method and dependency injection, observer, locking and scheduling, all of which I have hit on in some form or another in assorted posts here while not necessarily calling them out as such patterns.

I always welcome your feedback and allow anonymous comments so feel free to comment on anything. Spam and off-topic/inappropriate comments are and always will be removed.

Full series of posts:
Part One: Starting with MVVM
Part Two: The MVVM solution structure and basic framework
Part Three: Base Classes
Part 4: Sampler View, View Model and Model
Part 5: Running and working with the TPL samples
Part 6: Parallel.For Sample
Part 7: Using Parallel.For effectively
Part 8: Adding a New Sample, Matrices Multiplication
Part 9: Basic Exception handling with the AggregateException
Part 10: Loop control of the Parallel.For and .ForEach
Part 11: Cancelling Threads with the CancellationTokenSource – The MVVM
Part 12: Cancelling Threads with the CancellationTokenSource – The Code
Part 13: Async/Await

Thanks,
Brian

The Task Parallel Library Sampler – Part 13: Async/Await

Previous Post in this series:
Part 12: Cancelling Threads with the CancellationTokenSource – The Code

This sample derives from a Microsoft example and an updated solution is available here.

AsyncAwaitSample model:

public class AsyncAwaitSample : Sample
{
	public override string SampleName
	{
		get { return "Async/Await Sample"; }
	}

	public override bool ImageRequired
	{
		get { return false; }
	}

	public async override void Run(System.Drawing.Bitmap bmp = null, Action<string> UpdateLog = null)
	{
		Stopwatch s = new Stopwatch();
		s.Start();

		UpdateLog("Step 1 (Run 1): Starting an await call to an asyncronous method.");
		int result = await AccessTheWebAsync("Run 1", UpdateLog);
		UpdateLog("Step 6 (Run 1): Done await call to an asyncronous method.");

		//this works and will even run asynchronously but won't wait on any result.
		//more then likely we will be long gone from this method before the method below is done
		UpdateLog(Environment.NewLine + "Step 1 (Run 2): Starting an async call without await and no result.");
		AccessTheWebAsync("Run 2", UpdateLog);
		UpdateLog("Step 6 (Run 2): Done with the async call without await and no result");

		s.Stop();
		RunTime = s.Elapsed;
	}

	// Three things to note in the signature: 
	//  - The method has an async modifier.  
	//  - The return type is Task or Task<T>. (See "Return Types" section.)
	//    Here, it is Task<int> because the return statement returns an integer. 
	//  - The method name ends in "Async."
	async Task<int> AccessTheWebAsync(string runDesignation, Action<string> UpdateLog)
	{
		// You need to add a reference to System.Net.Http to declare client.
		HttpClient client = new HttpClient();

		// GetStringAsync returns a Task<string>. That means that when you await the 
		// task you'll get a string (urlContents).
		// This also allows you set a lot of properties on the task rather then just running
		// it if you need to.
		Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");
		UpdateLog("Step 2 (" + runDesignation+ "): Sleeping for ten seconds.");
		await Task.Delay(10000);
		UpdateLog("Step 3 (" + runDesignation+ "): Woke up.");
		UpdateLog("Step 4 (" + runDesignation+ "): Getting the web page.");
		// The await operator suspends AccessTheWebAsync. 
		//  - AccessTheWebAsync can't continue until getStringTask is complete. 
		//  - Meanwhile, control returns to the caller of AccessTheWebAsync. 
		//  - Control resumes here when getStringTask is complete.  
		//  - The await operator then retrieves the string result from getStringTask. 
		// This could also have been done as 
		// string urlContents = await client.GetStringAsync("http://msdn.microsoft.com");
		string urlContents = await getStringTask;
		UpdateLog("Step 5 (" + runDesignation+ "): Got the web page.");
		// The return statement specifies an integer result. 
		// Any methods that are awaiting AccessTheWebAsync retrieve the length value. 
		return urlContents.Length;
	}
}

There are two runs here, one shown using the keyword “await” with an asyncronous method and another run just running an asyncronous method without using “await”. It is very important to understand the conventions when using async. That is the name of the method should contain “async” in it. As an example, the HttpClient.GetStringAsync() makes it obvious that it is an async method. As shown in the comments, when calling an async method with await, the current thread calls the method and then waits for the method to return before continuing. If an asyncronous method is called without using await, a seperate thread is spun off and execution continues on. This can be very dangerous if there are results you’re waiting for from an asyncrounous method.

Run results:

Starting Async/Await Sample
Step 1 (Run 1): Starting an await call to an asyncronous method.
Step 2 (Run 1): Sleeping for ten seconds.
Completed Async/Await Sample
Async/Await Sample ran in 00:00:10.0173992

Step 3 (Run 1): Woke up.
Step 4 (Run 1): Getting the web page.
Step 5 (Run 1): Got the web page.
Step 6 (Run 1): Done await call to an asyncronous method.

Step 1 (Run 2): Starting an async call without await and no result.
Step 2 (Run 2): Sleeping for ten seconds.
Step 6 (Run 2): Done with the async call without await and no result
Step 3 (Run 2): Woke up.
Step 4 (Run 2): Getting the web page.
Step 5 (Run 2): Got the web page.

Looking at Run 1 you can see that AsyncAwaitSample.Run() is started, the first run is started and then we get the message that the sample is done. But why? Because we’re calling the run method, which is asynchronous, without await, down in the Sampler model. As such, the calling code calls the method, a thread gets spun up, and then execution continues in the original calling code. It never waits, just continues. So why define the method as “async”? Because the only way to use await with an asynchronous method is if the method itself is async. If you look at Run 2, it is even more obvious what happens when you call an async method without using await. Run 1, which uses await, runs the steps sequentially (other then the messages from Sampler model). Run 2 clearly does the steps out of order.

Another important point, the Run method is defined by a base class, as such the Sampler model is just calling run on all it’s samples. But what is interesting is that we are able to make Run into an async method, which we have to do to use await, and we are given no warning from Sampler that we may be calling an async method without using await. Now, in AsyncAwaitSample we are given a warning that for Run 2 we are calling an async method without await. But there it is more obvious that we are doing so.

In the first post in this series I said there would be 15 posts but it looks like there will be only 14. The next post will be a wrap-up/final to this series.

Thanks,
Brian

Previous Post in this series:
Part 11: Cancelling Threads with the CancellationTokenSource – The MVVM

So now that we’ve covered the MVVM, which you saw was pretty trivial to implement, let’s cover the actual sample.

CancellationSample.Run

public override void Run(System.Drawing.Bitmap bmp = null, Action<string> UpdateLog = null)
{
	Stopwatch s = new Stopwatch();
	s.Start();

	IsRunning = true;

	CancellationTokenSource = new CancellationTokenSource();
	CancellationTokenSource.Token.Register(() => { IsRunning = false; });

	var options = new ParallelOptions { CancellationToken = CancellationTokenSource.Token };
	try
	{
		Parallel.ForEach(WhileTrue(), options, i =>
		{
			while (!options.CancellationToken.IsCancellationRequested)
			{
				UpdateLog("Sleeping in Cancellation Sample at " + i);
				Thread.Sleep(ran.Next(1000));
			}
		});
	}
	catch (OperationCanceledException)
	{
		UpdateLog("Operation has been cancelled."); ;
	}

	s.Stop();
	RunTime = s.Elapsed;
}

public static IEnumerable<int> WhileTrue()
{
	for (int i = 0; ; i++)
		yield return i;
}

We start by instantiating the CancellationTokenSource that holds our token. We have to do this for each run or else the token is already cancelled and the threads in the Parallel.ForEach won’t spawn.

Line 9 is pretty interesting. We’re registering a call-back to fire when the token gets cancelled. Here we set “IsRunning” to false but you can put any delegate here. This way when whatever code external to us cancels the token then we can handle the IsRunning.

Next we instantiate a ParallelOptions, setting the CancellationToken to the Token of the CancellationTokenSource.

The most important thing with all this is to note that cancelling the CancellationTokenSource doesn’t stop any threads, it just prevents more threads from being spawned. Because of this we have to check in our while loop if the CancellationToken has been cancelled and if it has been then stop. When canceling the CancellationTokenSource this will cause an OperationCanceledException to be thrown. This way you can handle if there is any clean-up that needs to happen if your Parallel.For and .ForEach may not have completed. In our case I’m using a “WhileTrue” that just goes on infinitely.

Up next I’ll go into async/await.

Thanks,
Brian

Previous Post in this series:
Part 10: Loop control of the Parallel.For and .ForEach

Next up we’ll work on cancelling threads with the CancellationTokenSource. This is really a two parter where the first part will deal with the changes I had to make to integrate a new view and the second part covering the sample model. There is an update set of code available.

Since we’re going to want to cancel a thread once we’ve started it we’ll need a mechanism for the user to do so. Working from the model to the view model to the view we’ll see how I do this.

CancellationSample

public class CancellationSample : Sample
{
	public override string SampleName
	{
		get { return "Cancellation Sample"; }
	}

	public override bool ImageRequired
	{
		get { return false; }
	}

	bool isRunning = false;
	public bool IsRunning
	{
		get { return this.isRunning; }
		set
		{
			if (this.isRunning != value)
			{
				this.isRunning = value;
				this.RaisePropertyChanged("IsRunning");
			}
		}
	}
			
	public CancellationTokenSource CancellationTokenSource { get; set; }

	private static Random ran = new Random();

	public override void Run(System.Drawing.Bitmap bmp = null, Action<string> UpdateLog = null)
	{
		Stopwatch s = new Stopwatch();
		s.Start();

		IsRunning = true;

		CancellationTokenSource = new CancellationTokenSource();
		CancellationTokenSource.Token.Register(() => { IsRunning = false; });

		var options = new ParallelOptions { CancellationToken = CancellationTokenSource.Token };
		try
		{
			Parallel.ForEach(WhileTrue(), options, i =>
			{
				while (!options.CancellationToken.IsCancellationRequested)
				{
					UpdateLog("Sleeping in Cancellation Sample at " + i);
					Thread.Sleep(ran.Next(1000));
				}
			});
		}
		catch (OperationCanceledException)
		{
			UpdateLog("Operation has been cancelled."); ;
		}

		s.Stop();
		RunTime = s.Elapsed;
	}

	public static IEnumerable<int> WhileTrue()
	{
		for (int i = 0; ; i++)
			yield return i;
	}
}

Above you can see the CancellationTokenSource we’re using but as I said I’ll go into further detail on the next post. For the most part this is virtually identical to the other samples provided. There are two new properties exclusive to this class, the IsRunning property that defines when the run method is started and ended and the CancellationTokenSource itself.

CancellationSampleViewModel

public class CancellationSampleViewModel : SampleViewModel
{
	public CancellationSampleViewModel(CancellationSample Sample) : base(Sample) { }
	
	public void CancelRun()
	{
		((CancellationSample)Sample).CancellationTokenSource.Cancel();
	}
}

The view model for the CancellationSample couldn’t be much easier. As you know, view models act as a go-between from the model and the view. In this case we expose a method to cancel a run where we just call the cancel method on the CancellationTokenSource.

CancellationSampleView.xaml

<UserControl x:Class="TPLSamples.Views.CancellationSampleView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
             xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <UserControl.Resources>
        <BooleanToVisibilityConverter x:Key="BoolToVis" />
    </UserControl.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <CheckBox Grid.Row="0" IsChecked="{Binding Sample.IsEnabled, Mode=TwoWay}" Content="{Binding Sample.SampleName}" ToolTip="{Binding Sample.SampleName}" />
        <Button Grid.Row="1" Margin="5" Content="Cancel Run" Visibility="{Binding Path=Sample.IsRunning, Converter={StaticResource BoolToVis}}">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="Click">
                    <ei:CallMethodAction TargetObject="{Binding}" MethodName="CancelRun" />
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </Button>
    </Grid>
</UserControl>

This view is similiar to the generic SampleView.xaml with the addition of the button for cancelling the run. There are a few points of note. The first is the Interaction.Triggers to fire on the button click event. We bind to the CancelRun method of the view model that was previously mentioned. This is just like how the Submit/Reset buttons are set up. Next is the BooleanToVisibilityConverter in the resources of the control which is a standard class available in “System.Windows.Controls”. We use that to set the visibility of the button based on when the sample is running. As with the other view we bind directly to the model property, in this case “IsRunning”. As mentioned in a previous post this isn’t the truest of MVVM as these properties should be exposed in the ViewModel. This is problematic as it introduces a dependency directly between your view and model. In this instance, however, the code is a lot cleaner to understand when we just bind directly to the model and I feel justified in using this way.

As with nearly all MVVM implementations the code-behind is just the boiler-plate code created for us.

Finally I need to discuss what I had to change to the code to support the new model. In the SamplerViewModel I added it as I’ve added other models and view models. What had to really change is the ItemsControl.

SamplerView.xaml ItemsControl

<ItemsControl Grid.Row="1" IsTabStop="False" ItemsSource="{Binding Samples}">
	<ItemsControl.ItemsPanel>
		<ItemsPanelTemplate>
			<WrapPanel Orientation="Horizontal" IsItemsHost="True" Utility:MarginUtilities.Margin="5" />
		</ItemsPanelTemplate>
	</ItemsControl.ItemsPanel>
	<ItemsControl.Resources>
		<DataTemplate DataType="{x:Type ViewModels:CancellationSampleViewModel}">
			<Views:CancellationSampleView DataContext="{Binding}" />
		</DataTemplate>
		<DataTemplate DataType="{x:Type ViewModels:SampleViewModel}">
			<Views:SampleView DataContext="{Binding}" />
		</DataTemplate>
	</ItemsControl.Resources>
	<!--<ItemsControl.ItemTemplate>
		<DataTemplate>
			<Views:SampleView DataContext="{Binding}" />
		</DataTemplate>
	</ItemsControl.ItemTemplate>-->
</ItemsControl>

I left commented out the ItemTemplate for the SampleView. Since we were originally only using just the base SampleView this made since. Now that we’ve expanded the Views possible we need to provide a mapping of the view models to the correct view as we’re going to do this in the resources. You can see all we’re doing is defining for each view model a view. The order is not important and the binding will take care of assigning the most restrictive type possible. So even if we flip the two data templates the final binding works correctly.

That’s all for now. As I mentioned in next week’s post I’ll go into detail on the sample and what it’s doing.

Thanks,
Brian

Previous Post in this series:
Part 9: Basic Exception handling with the AggregateException

Generally we’re used to having a break when doing loops. If you’ve tried to continue or break out of a parallel loop you get:

No enclosing loop out of which to break or continue

“continue” is the easy case, just return. But breaking is a bit more complex. Do you want to stop all threads? Do you want to run all threads up to the point where you break? Well, you have a choice. Below and in the included solution are two samples showing how to handle loop control.

LoopBreakSample:

public class LoopBreakSample : Sample
{
	public override string SampleName
	{
		get { return "Loop Break Sample"; }
	}

	public override bool ImageRequired
	{
		get { return false; }
	}

	protected int MaxValue { get { return 50; } }
	protected int BreakValue { get { return 20; } }

	public override void Run(System.Drawing.Bitmap bmp = null, Action<string> UpdateLog = null)
	{
		Stopwatch s = new Stopwatch();
		s.Start();

		UpdateLog("Running to " + MaxValue);
		var loopResult = Parallel.For(0, MaxValue, (int i, ParallelLoopState loop) =>
		{
			UpdateLog("Starting " + i);
			if (i == BreakValue)
			{
				UpdateLog("Breaking " + i);
				loop.Break();
				return;
			}

			Thread.Sleep(100);
		});
		UpdateLog("IsCompleted == " + loopResult.IsCompleted);
		if (!loopResult.LowestBreakIteration.HasValue)
			UpdateLog("LowestBreakIteration has no value");
		else
			UpdateLog("LowestBreakIteration.Value == " + loopResult.LowestBreakIteration.Value);

		s.Stop();
		RunTime = s.Elapsed;
	}
}

There are a few things going on here besides your normal delegate for the loop. First is that the parameters for the lambda that define the delegate have a ParallelLoopState. It is this loop state that we are calling .Break().

Second is that we use the ParallelLoopResult to see if the loop has completed and what the lowest iteration was when break was called.

It is critical that you understand how break works. Per the documentation:

Break may be used to communicate to the loop that no other iterations after the current iteration need be run. For example, if Break() is called from the 100th iteration of a for loop iterating in parallel from 0 to 1000, all iterations less than 100 should still be run, but the iterations from 101 through to 1000 are not necessary.

This is very important. Break() will continue to spawn threads until the point is reached had the break been called as if this was a standard loop. LowestBreakIteration is set so the user knows at what point Break() was called.

The result of running this will look similar to:

Starting Loop Break Sample
Running to 50
Starting 12
Starting 0
Starting 6
Starting 18
Starting 24
Starting 30
Starting 36
Starting 42
Starting 13
Starting 1
Starting 7
Starting 25
Starting 31
Starting 43
Starting 37
Starting 2
Starting 14
Starting 8
Starting 20
Breaking 20
Starting 3
Starting 15
Starting 9
Starting 16
Starting 10
Starting 17
Starting 5
Starting 11
IsCompleted == False
LowestBreakIteration.Value == 20
Completed Loop Break Sample

As you can see, the break is called at 20 like it should have been. New threads, however, were spawned to makes sure that “i” still reaches 20 where Break() was called.

UPDATE: As you read the above list of started threads there seems to be a couple of threads missing if we’re really running to 20. I changed out the maximum number of threads to spawn (with ParallelOptions) to 2 and fiddled with some other code to get it to break early. It worked as the documentation states so I’m not sure why there are some missing numbers in the above results.

So what if you want to just stop new thread creation and not continue on? That is where Stop() is used.

LoopStopSample:

public class LoopStopSample : LoopBreakSample
{
	public override string SampleName
	{
		get { return "Loop Stop Sample"; }
	}

	public override void Run(System.Drawing.Bitmap bmp = null, Action<string> UpdateLog = null)
	{
		Stopwatch s = new Stopwatch();
		s.Start();

		UpdateLog("Running to " + MaxValue);
		var loopResult = Parallel.For(0, MaxValue, (int i, ParallelLoopState loop) =>
		{
			if (i > BreakValue)
			{
				UpdateLog("Stopping at " + i);
				loop.Stop();
				return;
			}
			UpdateLog("Starting at " + i);
			while(!loop.IsStopped)
			{
				Thread.Sleep(10);
			}
		});
		UpdateLog("IsCompleted == " + loopResult.IsCompleted);
		if (!loopResult.LowestBreakIteration.HasValue)
			UpdateLog("LowestBreakIteration has no value");
		else
			UpdateLog("LowestBreakIteration.Value == " + loopResult.LowestBreakIteration.Value);

		s.Stop();
		RunTime = s.Elapsed;
	}
}

Here Stop() is called when we reached a value greater then BreakValue. Stop() is different then Break() in that it will cause no more thread to be generated at all. Any threads that were created will continue to run. When Stop() is called the parallelLoopState.IsStopped will also be set so other threads know that they should stop. LowestBreakIteration will have no value though. This is only set when Break() is called.

The result of running this will look similiar to:

Starting Loop Stop Sample
Running to 50
Starting at 0
Starting at 6
Starting at 12
Starting at 18
Stopping at 24
Stopping at 30
IsCompleted == False
LowestBreakIteration has no value
Completed Loop Stop Sample

You can see that as soon as Stop() is called no more threads are created even though there are still a lot of threads that haven’t been created up to the iterator.

So to sum up:

Action Break() Stop()
Thread Creation Continues spawning threads until the point is reached had this been a standard loop. Any threads already created are allowed to finish. No more threads are created. Any threads already created are allowed to finish.
LowestBreakIteration Set at the point when Break() is first called. Not set
IsStopped Not set Sets to true when called

Up next is a sample using CancellationTokenSource to cancel the threads from running outside of the loop.
Thanks,
Brian

Previous Post in this series:
Part 8: Adding a New Sample, Matrices Multiplication

In the updated solution you’ll find two new models, AggregateExceptionNoCatchSample and AggregateExceptionCatchSample. The TPL provides a convienient exception handling mechanism in the form of an AggregateException.

If you run through a Parallel.For or .ForEach and an exception is thrown in one of the threads, no more threads are created and any exceptions that are thrown across all threads are wrapped in an Aggregate exception and that is thrown upon leaving the Parallel.For or .ForEach.

The first sample here, AggregateExceptionNoCatchSample, throws an exception when getting to row 100. Of course remember that we’re spinning off threads and the row we’re looking at could be random. The code could run all rows up to 100 and than get thrown or get could get row 400 after only processing row 8.

AggregateExceptionNoCatchSample:

public class AggregateExceptionNoCatchSample : Sample
{
	//used by DrawGreyScale to set the number of rows we started
	private int rowsStarted = 0;

	public override string SampleName
	{
		get { return "Aggregate Exception - Don't Catch Exceptions Sample"; }
	}

	public override bool ImageRequired
	{
		get { return true; }
	}

	public override void Run(System.Drawing.Bitmap bmp = null, Action<string> UpdateLog = null)
	{
		Stopwatch s = new Stopwatch();
		s.Start();

		try
		{
			rowsStarted = 0;
			DrawGreyScale(bmp, UpdateLog);
		}
		catch (AggregateException ae)
		{
			UpdateLog("Started " + rowsStarted + " rows.");
			//if an exception is handled and true is returned then nothing happens
			//if an exception isn't handled and false is returned then all unhandled exceptions are rewrapped in
			//a new AggregateException and thrown again.
			ae.Handle((x) =>
			{
				if (x is StackOverflowException) // This we know how to handle.
				{
					UpdateLog("Handling a stack overflow exception.");
					return true;
				}
				else
				{
					UpdateLog("Unhandled exception.");
				}
				return false; // Let anything else stop the application.
			});
		}

		s.Stop();
		RunTime = s.Elapsed;
	}

	private void DrawGreyScale(System.Drawing.Bitmap bmp, Action<string> UpdateLog)
	{
		System.Drawing.Imaging.BitmapData bmData = bmp.LockBits(new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
		int stride = bmData.Stride;
		System.IntPtr Scan0 = bmData.Scan0;
		unsafe
		{
			byte* start = (byte*)(void*)Scan0;

			int height = bmp.Height;
			int width = bmp.Width;

			Parallel.For(0, height, y =>
			{
				UpdateLog("Starting line " + y.ToString());
				Interlocked.Increment(ref rowsStarted);
				byte* p = start + (y * stride);
				for (int x = 0; x < width; ++x)
				{
					byte blue = p[0];
					byte green = p[1];
					byte red = p[2];

					p[0] = p[1] = p[2] = (byte)(.299 * red
						+ .587 * green
						+ .114 * blue);

					p += 3;
				}

				if (y >= 100)
				{
					UpdateLog("Throwing an exception at " + y);
					if (y % 2 == 0)
						throw new StackOverflowException("yeah, we got a stack overflow.");
					else
						throw new ArgumentNullException("yeah, we got a null argument.");
				}
			});
		}
		bmp.UnlockBits(bmData);
	}
}

As mentioned an exception is thrown in DrawGreyScale upon getting to row 100. In all likelihood multiple rows would have been spun off for rows greater then or equal to 100. All of these rows that throw an exception will get combined into an AggregateException. Inside of the AggregateException is a property titled “InnerExceptions” that contains all of these exceptions. For even rows a StackOverflowException is thrown (for no reason other then I wanted to throw that type) and for odd rows an ArgumentNullException is throws (for the same reason as the StackOverflowException).

In the .Run of AggregateExceptionNoCatchSample the call to .DrawGreyScale is wrapped in a try/catch for an AggregateException. Reading the documentation on ExceptionHandling in the TPL it is recommended you don’t wrap a call like this in a try/catch and not do anything with the exceptions. Uh, yeah, well, I hope you wouldn’t catch exceptions and not do something with them.

In the catch .Handle is being called that invokes the predicate passed in. This will iterate through all exceptions in the InnerExceptions of the AggregateException so you can handle each one individually. If you handle the exception the predicate should return a true so that AggregateException knows not to do anything with it. If you don’t handle the exception you should return false. If any exceptions aren’t handled they are wrapped in a new AggregateException and thrown outside of the handle method. This way if you get multiple types of exceptions and one appears you weren’t expecting it can be handled higher up in the stack.

In the sample it may actually kill the app because I only handle the StackOverflowException and not the ArgumentNullException which will get re-thrown.

AggregateExceptionCatchSample:

public class AggregateExceptionCatchSample : Sample
{
	//used by DrawGreyScale to set the number of rows we started
	private int rowsStarted = 0;

	public override string SampleName
	{
		get { return "Aggregate Exception - Catch Exceptions Sample"; }
	}

	public override bool ImageRequired
	{
		get { return true; }
	}

	public override void Run(System.Drawing.Bitmap bmp = null, Action<string> UpdateLog = null)
	{
		Stopwatch s = new Stopwatch();
		s.Start();

		try
		{
			rowsStarted = 0;
			DrawGreyScale(bmp, UpdateLog);
		}
		catch (AggregateException ae)
		{
			UpdateLog("Started " + rowsStarted + " rows.");

			ae.Handle((x) =>
			{
				UpdateLog("Handling an exception.");
				return true;
			});
		}

		s.Stop();
		RunTime = s.Elapsed;
	}

	private void DrawGreyScale(System.Drawing.Bitmap bmp, Action<string> UpdateLog)
	{
		ConcurrentQueue<Exception> exceptions = new ConcurrentQueue<Exception>();
		System.Drawing.Imaging.BitmapData bmData = bmp.LockBits(new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
		int stride = bmData.Stride;
		System.IntPtr Scan0 = bmData.Scan0;
		unsafe
		{
			byte* start = (byte*)(void*)Scan0;

			int height = bmp.Height;
			int width = bmp.Width;

			Parallel.For(0, height, y =>
			{
				try
				{
					UpdateLog("Starting line " + y.ToString());
					Interlocked.Increment(ref rowsStarted);
					byte* p = start + (y * stride);
					for (int x = 0; x < width; ++x)
					{
						byte blue = p[0];
						byte green = p[1];
						byte red = p[2];

						p[0] = p[1] = p[2] = (byte)(.299 * red
							+ .587 * green
							+ .114 * blue);

						p += 3;
					}

					if (y >= 100)
					{
						UpdateLog("Throwing an exception at " + y);
						if (y % 2 == 0)
							throw new StackOverflowException("yeah, we got a stack overflow.");
						else
							throw new ArgumentNullException("yeah, we got a null argument.");
					}
				}
				catch (StackOverflowException)
				{
					UpdateLog("Internally handled the StackOverflowException.");
				}
				catch (Exception e)
				{
					exceptions.Enqueue(e);
				}
			});
		}
		bmp.UnlockBits(bmData);

		if (exceptions.Count > 0)
			throw new AggregateException(exceptions);
	}
}

In the AggregateExceptionCatchSample the exceptions are caught in the Parallel.For and dropped into a ConcurrentQueue if we don’t handle it. Then upon exiting the Parallel.For, if any exceptions were queued we throw a new AggregateException passing in the queue so it can get handled above us.

So why do this? The biggest advantage is that you may be able to handle the exceptions right in the thread with no reason to kill all threads. This way, if there are any threads that have exceptions you can’t handle then let them bubble up in the AggregateException. In this sample we assume we can handle all exceptions in the .Run and just return true in the .Handle of the catch so we don’t kill the app for a sample but you will only want to return true if you handle the exception and false if you don’t. Up next is stopping and breaking in a Parallel.For and .ForEach.

Thanks,
Brian