Archive for August 2011

Added forum support for BitFlex.

I recently released BitFlex Framework 3.0, and I decided to add a forum for it as well. You can view the forum here. Since the framework is open source, the forum will provide a place for people to ask for help with the source code among other things.

Writing thread-safe event handlers with the Task Parallel Library in .NET 4.0

Download Example Code
TasksWithThreadSafeEvents.zip

In this article we will be using the following technologies:

  • .NET 4.0
  • Windows Forms (WinForms)
  • Task Parallel Library (TPL, part of .NET 4.0)

In a nutshell, I am talking about writing thread-safe events for WinForms. I’ve not ventured into the world of WPF quite yet, so this article may or may not apply to WPF.

Now, with that said, you may be familiar with the concept of BeginInvoke, EndInvoke, and Invoke to access WinForms controls safely from other threads. The amount of code to do that can be quite cumbersome, and to me it looks like speghetti. Another way to do it was by using ISynchronizeInvoke which you could wrap into a helper class, and do invoking in a single line of code. These methods all work great.

There are quite a few articles that explain how to do thread-safe and synchronized events with the Task Parallel Library, but they often are long and complicated. The other problem with the majority of these articles out there all assume one, single, horrific thing: You will always be writing your parallel code inside the form and have access to your controls other other referencable objects. Furthermore, they all seem to implement some sort of helper class that comes as an extra. In this article, my aim is a bit more specific. Take the System.Net.WebClient class for example. It exposes an event called DownloadProgressChanged. You know what is great about this? It’s thread-safe, and it doesn’t have a clue about your form or controls. That’s what this article is about. I am going to show you how to write a class with completely thread-safe events using the TPL and just a few lines of code.

The code:

//-----------------------------------------------------------------------------
// <copyright file="Counter.cs" company="DCOM Productions">
//     Copyright (c) DCOM Productions.  All rights reserved.
// </copyright>
//-----------------------------------------------------------------------------

namespace TasksWithThreadSafeEvents.Objects {
    using System;
    using System.Threading.Tasks;
    using System.Threading;

    internal class Counter {
        // CLR generated constructor

        #region Events

        /// <summary>
        /// Occurs when the counter has counted
        /// </summary>
        public event EventHandler CountChanged;
        private void OnCountChanged() {
            if (CountChanged != null) {
                CountChanged(this, new EventArgs());
            }
        }

        /// <summary>
        /// Occurs when the counter has completed counting
        /// </summary>
        public event EventHandler CountCompleted;
        private void OnCountCompleted(Task task) {
            if (CountCompleted != null) {
                CountCompleted(this, new EventArgs());
            }
        }

        #endregion

        #region Properties

        private int m_Maximum = 100;
        /// <summary>
        /// Sets the maximum value the counter will count to
        /// </summary>
        public int Maximum {
            get {
                return m_Maximum;
            }
            set {
                m_Maximum = value;
            }
        }

        #endregion

        #region Methods

        private void Count() {
            for (int i = 0; i < Maximum; i++) {
                Thread.Sleep(50);
            }
        }

        /// <summary>
        /// Runs the counter by starting from 0 and incrementing by one, until the counter reaches its maximum
        /// </summary>
        public void Run() {
            Task.Factory.StartNew(Count).ContinueWith(OnCountCompleted);
        }

        #endregion
    }
}

I shouldn’t have to explain the code, but I will say that the main difference you will see in this event model is that OnCountCompleted defines an argument of type Task. This is because we must specify a Action<Task> when calling ContinueWith when we run our task. We don’t care about the Task object in the event handler, we just want to notify the event that it was completed, and with this approach having to pass an Action<Task> is just a small side-effect.

Often in development you want to write components like this (not specifically a counter), but essentially a class (or wrapper) that does all the work you need to, and is thread-safe at the same time. The reason we do this is we don’t want to have to make it thread-safe everywhere we use it in UI. If I have a class that does not provide thread-safe events, that means I have to write all this thread-safe code in each UI that I use it in. The class we just went over is extremely simple, so let’s wire-up the progress.

First, we need to add a TaskScheduler field to the class.

#region Fields

private TaskScheduler m_TaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();

#endregion

This should be pretty self-explanatory, but in a nutshell we define this at class-scope, and it creates the object on the same thread that the class is created on (of course). So essentially, when you create the Counter class somewhere in your WinForm, the TaskScheduler is created on the same thread as the form: your UI thread.

Next, we need to actually report progress in our Count() method that actually does the counting. The cool thing about the Task Parallel Library is we can do this in a single line of code.

private void Count() {
    for (int i = 0; i &lt; Maximum; i++) {
        Thread.Sleep(50);
            Task.Factory.StartNew(() =&gt; OnCountChanged(),
            CancellationToken.None,
            TaskCreationOptions.None,
            m_TaskScheduler)
        .Wait();
    }
}

We are simply starting a new task using the existing TaskFactory, and hooking it up to our method that invokes the event handler. We don’t need to specifiy anything special for arguments, but we need to make sure we pass in our TaskScheduler. This is important, because the task scheduler will invoke the task on the thread the task scheduler is on: the UI thread.

The second important thing is that we are calling the Wait method. The reason we are doing this is because we want to give whatever hooks up to the event time to execute their logic. For example, a progress bar to update and paint.

That’s all there is too it.. let’s use the code in a simple WinForms app with a progress bar and a button.

//-----------------------------------------------------------------------------
// <copyright file="ShellForm.cs" company="DCOM Productions">
//     Copyright (c) DCOM Productions.  All rights reserved.
// </copyright>
//-----------------------------------------------------------------------------

namespace TasksWithThreadSafeEvents.Forms {
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using TasksWithThreadSafeEvents.Objects;

    public partial class ShellForm : Form {
        /// <summary>
        /// Instantiates a new instance of the TasksWithThreadSafeEvents.Forms.ShellForm class
        /// </summary>
        public ShellForm() {
            InitializeComponent();
        }

        private void OnButtonClick(object sender, EventArgs e) {
            Counter counter = new Counter();
            counter.CountChanged += OnCountChanged;
            counter.CountCompleted += OnCountCompleted;
            counter.Maximum = uxProgressBar.Maximum;
            uxProgressBar.Value = 0;
            counter.Run();
        }

        private void OnCountChanged(object sender, EventArgs e) {
            uxProgressBar.Value++;
        }

        private void OnCountCompleted(object sender, EventArgs e) {
            MessageBox.Show("The counter has reached its maximum", "Counter",
                MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
    }
}

The code looks clean, and it was very little work to implement. You could of course modify the code to actually report a value for progress if you wanted by creating your own class deriving from EventArgs, and passing the for-loop indexer to the event args of the event. I hope this helps those out there looking to write simple, thread-safe classes using the Task Parallel Library.

Download Example Code
TasksWithThreadSafeEvents.zip

BitFlex Framework released to the public as part of the Open Source Initiative.

OSI Approved License 100x137 BitFlex Framework released to the public as part of the Open Source Initiative.

Open Source Initiative

Get it now!
http://www.dcomproductions.com/products/bitflex/

I understand that almost no one knows what BitFlex is because it has never been exposed to the public before, so I will give you a small description.

BitFlex is a framework written in C# and targeted for .NET 3.5. It is a combination of the Microsoft         Composite Application Block (CAB) framework, WinForms controls, and Enterprise         services written by DCOM Productions. The core goal is to provide a powerful         framework of enterprise services, while also providing Windows UI Integration to         give your applications the “Windows Look and Feel”. BitFlex makes powerful         improvements to the existing .NET controls enabling the true Windows Experience,         and also introduces various other controls you see in Windows that are not         provided in .NET.

The current stable version of BitFlex is 3.0. It has been widely used by DCOM Productions in deployed products in production for clients and internal projects alike. Part of the reasoning behind releasing BitFlex is that I want developers to enjoy the same framework that has been used in my products, and to enjoy the numerous “Windows Look and Feel” controls I have provided, bundled with the power of Microsoft’s CAB framework, and the power of some of the Enterprise Services that come along with it.

Windows “Look and Feel” Controls
Microsoft’s .NET controls for Windows Forms are, to say the least, partial implementations, or at least limited. They don’t look anywhere near the same as the actual controls scattered around Windows. Some of the controls you notice this about immediately are the ListView control’s theming, the TextBox’s lack of cue banner text, or even the ProgressBar’s lack of the full implementation. Here is a fill list of the controls that are provided with fixed implementations.

  • CommandLink
  • ExplorerButton
  • ExplorerComboBox
  • ExplorerContextMenu
  • ExplorerLabelDivider
  • ExplorerListView
  • ExplorerMainMenu
  • ExplorerProgressBar
  • ExplorerSplitButton
  • ExplorerTextBox
  • ExplorerTreeView
  • ExplorerHyperCommandLink
BitFlex WinForms Controls 300x261 BitFlex Framework released to the public as part of the Open Source Initiative.

BitFlex WinForms Controls

As you can see the controls have the built-in Windows look and feel, or the “explorer style” as I call it. There are other libraries out there on the net that offer the same implementations, and I have not tried most of them. But with BitFlex this is a pretty complete list, and implementation. There are a couple bugs need to be worked out. One I can say off the bat is sorting the ListView causes it to lose its explorer style. This is an easy fix though, and is in the queue to be corrected.

Other useful WinForms Controls
BitFlex has other useful controls as well. I have provided a fully customizable progress bar control. You can make it work virtually any way to you want it to. It doesn’t support circular progress indication, custom shapes or the sort, though – it is a progress bar, and is meant to act as one. If you like how the Linux Ubuntu progress bars look, or maybe the Adobe Photoshop CS3 installer progress bars, or anything else, this can do the job, and more.

It also contains a fully design-time oriented Wizard control as well. Full design-time support for navigation, customization, and its easy to use. There are a lot of improvements it could use even still, but its a start at providing a well implemented Wizard control for your applications. I originally created this to use when writing custom installers, and it is used in the BitFlex setup project.

An implementation of the Windows Ribbon control is bundled in BitFlex. This, I did not write and it retains its original copyright information, but it is included never the less in the goal to provide Windows look and feel controls. Another interesting control is the AppBar, though not fully implemented yet as it wasn’t in the budget, there is one in BitFlex that does the basic job of an AppBar.

Enterprise Services
The enterprise services are really what make BitFlex even more useful, moreso than the WinForms controls.

  • Command Line Application Block to easily implement command line parameter handling in your programs
  • Windows Fonts classes which provide the latest Windows font color structures like Header, DocumentText, Link, Active Link, etc
  • Authentication services for SQL, Registry, or the ability to implement your own from the existing interfaces and classes
  • Fully functional global keyboard and mouse hooks and listeners with the full ability to disable various keyboard combinations (Windows Key, Alt+F4, etc)
  • Full implementation of various Windows Shell policies (WinlogonPolicy, NoDrivesPolicy, etc), there are about 20 of them and classes to implement more
  • IO services like CSV file, Initialization file for compatibility, etc
  • XDF, a simple and easy to use configuration format similar to an SLN file

There will always be improvements that can be made to BitFlex in everyway possible. This is part of the reason I made this open source. It is a pretty small framework, but it provides a few things that are definitely handy to developers. I hope that others get as good of a use out of it as I have.

MySQL support and Updates for FaultTrack

It’s been a few weeks since I’ve posted any real updates about the progression of FaultTrack. So what is the state of FaultTrack?

Performance Optimizations
Thanks to our pre-release testers, I was brought awareness of various performance issues in FaultTrack. I have spent a considerable amount of time doing performance analyzation runs on the software, and have made considerable improvements to performance in every area of the application. The performance in a deployed environment heavily relies on the speed of the database server serving your requests, but ultimately if you have a fast database server, FaultTrack will be holding its own just fine.

Bug Fixes
Before I branched the software to implement support for multiple databases, the software was committed to source control with zero known bugs. To date, there are still no known issues. This isn’t to say there won’t be any since I am still testing and polishing various parts of the system, but as of now there are no known issues.

Bug Reporting System
I like to get people involved, so I reached out to my friend Zack at Unified Technologies and had him develop the bug reporting feature in FaultTrack. After it was finished I ran it through QA, polished some things, and thus it has been included in FaultTrack.

BugReportFeature 300x170 MySQL support and Updates for FaultTrack

Configuration System
A configuration system is being engineered to replace the one you see in the image below to make it a little more friendly and functional. I would mainly be adding support to configure multiple servers. I know I will use this feature, and in a real environment you may be using the same issue tracking software for multiple vendors, projects, workgroups, or even individually.

DatabaseDrivers 300x171 MySQL support and Updates for FaultTrack

Support for Oracle’s MySQL Engine
Not everyone has access to a MSSQL Engine, so I felt it was important enough to set aside time from the normal business plan to implement. Side effects of this mean that you now must have .NET 4.0 Framework installed to use FaultTrack. This shouldn’t be an issue for most as it is included in Windows Update, so your system is likely to have it installed already, but for those who don’t FaultTrack will not run without it. Currently I have tested this with the MySQL 5.5 with great success. It uses the Microsoft ADO.NET Entity Framework which will allow me to provide more database support in the future.

That’s it for now. If you have feedback, or questions I would love to hear it. A release date has been set which I will not disclose as of yet, but it is very soon and you can look forward to all the FaultTrack’ing goodness. I will say that hosted solutions will be available for those who do not have access to any type of storage engine, but more details will be available when I release it.

Limitations of Entity Framework support with MySQL 6.4.3 Connector/Net

I started learning the Entity Framework so I can add support for MySQL side-by-side MSSQL in FaultTrack Professional (issue tracking software I am developing), and I started to run into quite a few limitations with MySQL.

#1    DDL Generation (SSDLToMySQL.tt (VS))
The MySQL DDL Generation Template has some shortcomings. The most obvious that I ran into was max-length string fields. I had a field named ‘StackTrace’ that in MSSQL is nvarchar(MAX). Now in MySQL, the equivelent should simply be varchar(65535), but if you try to run a script to create a field you will get an error. This means that when you generate your DDL script that you have to go back and manually change it. This is because MySQL will actually expect you to use text instead of varchar(65535), and will throw an error.

#2 Guid (UNIQUEIDENTIFIER) Support
UUID() was introduced in later versions of MySQL, and moreso than that you MySQL now treats CHAR(36), BINARY(16) as guid type. The problem with this is when you start using this in your entity lambda expressions, you start to get errors thrown. Take this code example:

///<summary>
/// Returns the end result permission for the specified account and the associated Team Project. This resolves all inherited and override permissions
/// </summary>
public AccountPermissions GetTeamProjectPermission(System.Guid accountID, int collectionID, int projectID) {
    using (FaultTrackObjectContext context = new FaultTrackObjectContext(Settings.EntityConnectionString)) {
        Account account = context.Accounts.Single(a => a.ID == accountID);
        if (account.Role == AccountRoles.Administrator.ToString()) {
            return AccountPermissions.Grant;
        }
        else if (account.Role == AccountRoles.ProjectManager.ToString()) {
            return GetTeamProjectProjectManagerPermission(context, account, collectionID, projectID);
        }
        else if (account.Role == AccountRoles.Developer.ToString()) {
            return GetTeamProjectDeveloperPermission(context, account, collectionID, projectID);
        }
    }
    return AccountPermissions.Revoke;
}

Specifically notice the lambda expression a => a.ID == accountID. This line actually will throw a InvalidOperationException, “The sequence contains no elements”. I know I had exactly one matching element in the database, so I did a little debugging:

sMSjY 300x168 Limitations of Entity Framework support with MySQL 6.4.3 Connector/Net

Sure enough, what I found was by expanding the results view, that I did indeed have exactly one matching element. So what the heck? The lambda expression is failing; a => a.ID == accountID resolves to false and no matching elements are found. This is because of the way that MySQL stores the Guid. Even though your DDL looks good, your SSDL mappings look great, and your code looks even better, under-the-hood the provider implementation for Guid handling is not properly done. I’ve not looked at it myself, but some other devs I have spoken with have talked about how the connector uses ConvertTo and the conversion fails. Whatever the case may be under-the-hood in the connector, it simply does not work.

What I ended up doing, which was a benefit to my software anyway, was swapping all the primary keys from Guid types to integer types. The bottom line is, Entity has a lot of shortcomings, and it works best with primitive types. Actually, the issue with primitive types deserves its own explanation.

#3 Primitive Types
I want you to take a look at this code.

private bool PermissionConflicts() {
    bool conflicts = false;
    /* required for entity queries */ int accountID = (uxAccounts.SelectedItem as Account).ID;
    /* required for entity queries */ int permission = (int)(AccountRoles)uxPermission.SelectedItem;
    /* required for entity queries */ int grantPermission = (int)AccountPermissions.Grant;
    /* required for entity queries */ int readPermission = (int)AccountPermissions.Read;
    /* required for entity queries */ int revokePermission = (int)AccountPermissions.Revoke;
    switch (m_PermissionType) {
        case PermissionType.TeamCollection:
            if (Context.TeamCollectionPermissions.Any(predicate => predicate.AccountID == accountID
                && permission == grantPermission
                && predicate.TeamCollectionID == m_TeamCollection.ID)) {
                    if (permission == revokePermission || permission == readPermission) {
                        conflicts = true;
                    }
            }
            if (Context.TeamCollectionPermissions.Any(predicate => predicate.AccountID == accountID
                && permission == readPermission
                && predicate.TeamCollectionID == m_TeamCollection.ID)) {
                if (permission == grantPermission || permission == revokePermission) {
                    conflicts = true;
                }
            }
            if (Context.TeamCollectionPermissions.Any(predicate => predicate.AccountID == accountID
                && permission == revokePermission
                && predicate.TeamCollectionID == m_TeamCollection.ID)) {
                    if (permission == grantPermission || permission == readPermission) {
                    conflicts = true;
                }
            }
            break;
        case PermissionType.TeamProject:
            if (Context.TeamProjectPermissions.Any(predicate => predicate.AccountID == accountID
                && permission == grantPermission
                && predicate.TeamProjectID == m_TeamProject.ID)) {
                    if (permission == revokePermission || permission == readPermission) {
                        conflicts = true;
                    }
            }
            if (Context.TeamProjectPermissions.Any(predicate => predicate.AccountID == accountID
                && permission == readPermission
                && predicate.TeamProjectID == m_TeamProject.ID)) {
                if (permission == grantPermission || permission == revokePermission) {
                    conflicts = true;
                }
            }
            if (Context.TeamProjectPermissions.Any(predicate => predicate.AccountID == accountID
                && permission == revokePermission
                && predicate.TeamProjectID == m_TeamProject.ID)) {
                    if (permission == grantPermission || permission == readPermission) {
                    conflicts = true;
                }
            }
            break;
    }
    return conflicts;
}

Specifically, this:

predicate =>
       predicate.AccountID == accountID
    && permission == grantPermission
    && predicate.TeamCollectionID == m_TeamCollection.ID

In this lambda expression, we are operating on primitive types. This is fine, but when you are dealing with non-primitive types, the provider (not just MySQL’s provider), cannot properly convert the non-primitive types into primitive types, and the conversion fails, thus throwing an exception.

Prior to moving to Entity when the software was built on DLinq (Linq to SQL), the lamda was easily expressible:

predicate =>
    predicate.Account == uxAccounts.SelectedItem as Account
    && (AccountPermissions)predicate.Permission == AccountPermissions.Grant
    && predicate.TeamCollectionID == m_TeamCollection.ID

Unfortunately you cannot do that with Entity (hopefully I can use the term ‘yet’). I may write more on the Entity Framework; I am still learning it and it has a lot of potential. Most everything seems to have some workaround, but these were some of the annoyances I ran into that made me think twice about adding support for MySQL. Not everyone has access to an MSSQL Engine and MySQL is the other popular choice among others, so it really is a must.