Task Parallel Library Cheat Sheet

Saturday, October 09, 2010 / Posted by Luke Puplett / comments (0)

While I’d followed Mr Toub and his gang while they were making the TPL, I’ve since slept and forgotten it all. So I can always consider a concurrent approach to my classes, I thought I’d make a very simple overview ‘cheat sheet’ and stick it to the wall.

Get it here.

Labels: , , ,

Flowing Custom Control Values to ViewModel/Bindings

Friday, January 15, 2010 / Posted by Luke Puplett / comments (0)

This article discusses an issue I had when making a custom login box control, particularly the issue of getting the values in the username and password boxes to flow back down to the view-model. The issue might be my design, which could be fundamentally wrong, if only I knew of another way to do it.

The problem with Windows Presentation Foundation and its more promiscuous sister, Silverlight, is that its as good as it is bad. That is, its hard to deny its brilliance when you're carving out complex drawings and alpha gradients, adding subtleties to button animations and then there's the whole hardware accelerated 3D bit. But its bloody complicated because its mandate is to be everything to everyone and when so much is done for you all that stuff has to be massively multifaceted.

My LoginControl uses the parts and states model and the WPFToolkit to get at the VisualStateManager. I won't go into these things as they're documented enough and Karen Corby has a great MIX session video on it, too.

So I have a few parts, two TextBox controls and a Button. You can guess that these are username, password and the logon button.

Firstly, and I'll get this one over and done with quickly: I don't use the PasswordBox control. It does not support data binding because it takes a cautious approach and does things securely. Instead I apply a strikethrough formatting to a regular TextBox within its default style in generic.xaml.

You can see how this is done by reading my comments at the bottom of the MSDN article on the PasswordBox.

Welcome to my LoginControl

Cutting straight to the meat of the implementation, my control has the following properties:

  • private TextBox UsernameTextBox // the property which stores the TextBox UI control part/element for the username
  • private TextBox PasswordTextBox // the property which stores the TextBox UI control part/element for the password
  • public string Username // the dependency property which stores the username that can be bound to from a view model
  • public string Password // ditto but for the password

Because I can't bind my view model to a property of a the LoginControl's username TextBox and I don't want to expose the TextBox controls publicly, I use the following trick to hook up a binding between the TextBox.Text dependency property and LoginControl.Username (ditto for the password):

private TextBox UsernameTextBox
{
    get
    {
        return (TextBox)GetValue(UsernameTextBoxProperty);
    }
    set
    {
        // Detach observer from outgoing value.
        //
        var oldValue = this.UsernameTextBox;
        if (oldValue != null)
        {
            BindingOperations.ClearAllBindings(oldValue);
            oldValue.GotKeyboardFocus -= new KeyboardFocusChangedEventHandler(TextBoxes_GotKeyboardFocus);
            oldValue.KeyUp -= new KeyEventHandler(Username_KeyUp);
        }

        SetValue(UsernameTextBoxProperty, value);

        if (value != null)
        {
            value.SetBinding(TextBox.TextProperty, new Binding("Username")
            {
                Source = this,
                Mode = BindingMode.TwoWay
            });
            value.GotKeyboardFocus += new KeyboardFocusChangedEventHandler(TextBoxes_GotKeyboardFocus);
            value.KeyUp += new KeyEventHandler(Username_KeyUp);
        }
    }
}

And once that's done there's nothing else to consider except that when adding my LoginControl to my XAML page, I need to hook up the binding to the appropriate properties in the view model. That's easy:

Username="{Binding Path=Username, Mode=TwoWay}" Password="{Binding Path=Password, Mode=TwoWay}"

No worries there.

In Practice it Fails

The problem occurs when the login button is clicked and the ICommand is executed. The RelayCommand on the view model kicks in and my Action runs but if I stop the debugger right there I see that my view model does not have up-to-date Username and Password values!

My theory is that the binding system has not done its magic in between my typing of text and clicking of button. And although in theory the LostFocus events upon which data binding updates rely should have been triggered, my daisy-chained setup is somehow ballsing things up. Actually, there is a LostFocus on the username TextBox which should update the LoginControl.Username property, it doesn't, but even if it had, what's the activator to get the value to then jump from the Username property to its source down in my view model? By the way, flows up from source seem to work fine.

Whatever, I don't know. My solution was to grab each of my bindings and manually hit the UpdateSource method from within the login button's click method:

private void LoginButtonElement_Click(object sender, RoutedEventArgs e)
{
    var utbx = this.UsernameTextBox.GetBindingExpression(TextBox.TextProperty);
    utbx.UpdateSource();

    var ptbx = this.PasswordTextBox.GetBindingExpression(TextBox.TextProperty);
    ptbx.UpdateSource();

    var ubx = BindingOperations.GetBindingExpression(this, UsernameProperty);
    var pbx = BindingOperations.GetBindingExpression(this, PasswordProperty);

    ubx.UpdateSource();
    pbx.UpdateSource();

    if (this.PasswordTextBox != null)
    {
        if (!this.PasswordTextBox.IsFocused)
        {
            this.PasswordTextBox.Focus();
            if (!this.TryLoginButton.IsMouseOver)
                return;
        }
    }

    if (this.Command != null)
        this.Command.Execute(new KeyValuePair<stringstring>(this.Username, this.Password));
}

Which brings me right back to the point I made earlier about not doing this the right way. I'm not sure any other way would flow the values in time anyway. But then there's always the question of how everyone else doesn't seem to have this problem...

Labels: , , ,

WPF - How to Veto a Windows Shutdown

Friday, July 17, 2009 / Posted by Luke Puplett / comments (0)

...(even though you shouldn’t really).

The .NET Framework offers an event and a boolean argument property which is supposed to let you cancel the shutdown, but it often gets ignored and anyway, it doesn’t let you inform the user as to why your app is preventing them from rebooting. In this post I will cut and paste a few chunks of code from an application I’m working on which has, in the user’s interest, a need to stop the machine being switched off. Note that I am assuming some MVVM knowledge, but the principle is the same.

The System.Windows.Application class, from which a standard WPF application class or entrypoint derives, offers up a SessionEnding event to which you can add a handler and use the SessionEndingCancelEventArgs.Cancel property to veto a system shutdown.

Before I go any further, I must stress that Microsoft advises that you don’t do this unless its for a very important reason such as a CD-ROM being burned (which would ruin the disc, if interrupted). Guidance on this and on the timings of forced closures etc. and even the wording you should use in your reasons (which I’ll come to later) can be found here: http://msdn.microsoft.com/en-us/library/ms700677(VS.85).aspx

A bit hit and miss

So my point here is that Microsoft don’t want you to do this in the first place and that the wording on the Microsoft.Win32 version of effectively the same event is that it is not guaranteed. See here.

The way I look at it is if you feel you’ve good enough reason to stop a shutdown and potentially annoy your users (who will inevitably blame Windows and Microsoft), then the system to do it should be guaranteed. In fact, the system used by unmanaged coders is.

In the unmanaged world, session ending notification comes via a message sent to the window. As we have already a system to listen for this, we will just use the WPF SessionEnding event.

As I’m using the Model-View-ViewModel (MVVM) pattern, my code will need some extra explanations but the important stuff is clear.

My ViewModel knows not of the App class of my application, so this code goes outside of where the actual action takes place, in the App_Startup handler.

 

this.SessionEnding += new SessionEndingCancelEventHandler(App_SessionEnding);

void App_SessionEnding(object sender, SessionEndingCancelEventArgs e)
{
    int r = 1;
    if (e.ReasonSessionEnding == ReasonSessionEnding.Logoff)
        r = 0;

    bool cancel = false;
    this.MainWindowViewModel.OnShutdown(r, ref cancel);
    this.MainWindowViewModel.IsHandlingShutdownRequest = false;
    e.Cancel = cancel;
}

 

My ViewModel base class has an OnShutdown virtual method that can be implemented by any derived view model, I do this because a) the view model often knows of the application state better than the App class does (which has no real logic) and b) view models are usually tied to windows and the Win32 API needs the window for this thing to work.

I abstract the reason enums to make it more flexible. The ref cancel argument is used because I don’t want to block a shutdown and then have WPF unblock it by returning cancel = false

 

public override void OnShutdown(int shutdownType, ref bool cancel)
{
    if (this.IsHandlingShutdownRequest) // Subsequent calls allow time for first call.
    {
        int cycles = 0;
        while ((this.IsHandlingShutdownRequest) && cycles < 40) // 40*100 = 4000ms = 4sec
        {
            cycles++;
            System.Threading.Thread.Sleep(100);
        }
        System.Diagnostics.Trace.TraceInformation(
           @"The client waited and ignored a concurrent request by the OS to shutdown.");
        return;
    }
    this.IsHandlingShutdownRequest = true;

    System.Diagnostics.Trace.TraceInformation(
        @"The client handled a request by the OS to shutdown.");

    if (shutdownType > -1) // Change to whatever.
    {                
        this.DispatchMessage(@"Windows is shutting down.");

        if (this.IsBurningCD)
        {
            string msg = @"A CD is being burned.";            
            this.DispatchMessage(msg, true); // Uses dispatcher to put a
                     // message on screen, true make the window pop up.
            this.IsShutdownBlock = true; // Trigger for WPF animation/alert.

            System.Diagnostics.Trace.TraceWarning(msg);

            this.TryBlockShutdown(msg);
            cancel = true;

            this.IsHandlingShutdownRequest = false;
            return;
        }
    }

    this.DispatchMessage(@"Client is closing down.");

    // Some clean up tasks.

   
    System.Diagnostics.Trace.TraceInformation(
        @"The client closed itself in response to an OS shutdown.");

    this.TryUnblockShutdown();
    this.ShutdownApplication(); // Calls a delegate on the ViewModel (code not shown).
}

 

A few interesting points in the code above. The first section is experimental/stupid: I don’t want to have a subsequent/concurrent caller dismissed and give the wrong message back to Windows so I sit on them for 4s. I should use a wait handle but that would require complex explaining – plus it works as is.

The second bit reacts to the shutdown type and starts doing some UI work. This being MVVM, a storyboard triggered by a property here could flag up the impending doom to the user and add to their awareness of the problem.

Then a call is made to TryBlockShutdown() which does the dirty deed before cancel is set appropriately and the call returns.

Where execution determines that the shutdown is fine, a message is sent to the UI and a call is made to TryUnblockShutdown() just in case it was left ‘switched on’ somewhere.

Note that you may be able to use these methods outside of a handler and not call them from within – block and unblock in response to Before/AfterCDBurn events for example, however I prefer to handle the session ending event so I can make sure to unblock the shutdown.

Microsoft urges you to pre-empt rather than react on-the-fly to the session ending event. Registering a reason to block a shutdown seems to live in memory until the window is torn down, so you must always call the unblock API.

Important: When the window closes, your block will be lost. My own application, which is a background app, actually hides the main window upon closure to make sure that this doesn’t happen.

The certain way

Behind the TryBlockShutdown method is a call to ShutdownBlockReasonCreate within user32.dll. Calling managed code requires the UnmanagedCode permission and so this is demanded and gracefully dealt with here.

 

private bool TryBlockShutdown(string reason)
{
    bool rv = false;
    IntPtr hWnd;
    if (this.TryGetWindowHandle(out hWnd))
    {
        try
        {
            var p = new System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode);
            p.Demand();
            ((System.Windows.Threading.Dispatcher)this.Dispatcher).Invoke(new Action(
                delegate
                {
                    rv = ShutdownBlockReasonCreate(hWnd, reason);
                }));
        }
        catch { }
    }
    return rv;
}

[DllImport("user32.dll")]
private static extern bool ShutdownBlockReasonCreate(IntPtr HWnd,
    [MarshalAs(UnmanagedType.LPWStr)] string reason);

private bool TryUnblockShutdown()
{
    bool rv = false;
    IntPtr hWnd;
    if (this.TryGetWindowHandle(out hWnd))
    {
        try
        {
            var p = new System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode);
            p.Demand();
            ((System.Windows.Threading.Dispatcher)this.Dispatcher).Invoke(new Action(
                delegate
                {
                    rv = ShutdownBlockReasonDestroy(hWnd);
                }));
        }
        catch { }
    }
    return rv;
}

[DllImport("user32.dll")]
private static extern bool ShutdownBlockReasonDestroy(IntPtr HWnd);

 

So the main points to note here are the static extern bool methods, decorated with DllImportAttribute attributes and the MarshalAs attribute which appears before the string type definition for the reason argument.

Secondly and importantly, there is a call to this.Dispatcher which on my view model is the Dispatcher for the window so I can perform some work on the UI thread if I need to, which I do here.

Important: Calls to ShutdownBlockReasonXXX must be performed on the thread that owns/created the window to which the block applies and in WPF, this is the UI thread which is available via the Dispatcher.

Finally, there is TryGetWindowHandle which for me is defined in the base ViewModel class and skipping some of the logic for clarity, eventually ends up calling this code:

 

public static IntPtr GetWindowHandle(System.Windows.Window window)
{
    return (new System.Windows.Interop.WindowInteropHelper(window)).Handle;
}

 

And that’s that. More information about the Model-View-ViewModel can found at these places:

http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

http://jonas.follesoe.no/

And more on calling unmanaged code, here:

http://msdn.microsoft.com/en-us/library/aa288468(VS.71).aspx

Labels: , ,

Updating the UI from Asynchronous Ops

Friday, May 15, 2009 / Posted by Luke Puplett / comments (2)

A Technique for RIA UI Control Updates and MVVM

Its a fairly widely known fact of Windows programming that you can't update a UI control from the code executing in your painstakingly well-written worker object. There are a number of Framework constructs that are designed to help in these situations such as the Dispatcher as well as more low-level classes like the AsyncOperationManager which puts a slightly more friendly veneer over the SynchronisationContext. Whichever class you use, updating the UI usually involves writing dedicated methods in some place away from where the action is taking place.

I'm going to talk about using one of the simplest of the lot to re-unite things: BackgroundWorker.

You'll be able to go from writing asynchronous code straight to writing values to your view model with just a few lines in-between where the magic happens - all within the same method - so you can even pipe the variables declared and available within your concurrent method directly into the UI. Sounds to good to be true? Well I hope not because it seems to be working here.

About our Weapon of Choice

First up, a little bit of background about background, err worker. BackgroundWorker’s design centres on three events, DoWork, RunWorkerCompleted and ProgressChanged (I’d have called the first one RunWork but there you go).

Essentially, DoWork is triggered on a new thread-pool thread while the others are triggered on the UI thread.

Be careful though because ConsoleApplications seem not to jump back to Main Thread and I’m not totally sure if the design aim was to trigger on the UI thread specifically or just the same thread that the RunWorkerAsync method was called from.

I'd suggest reading more about it here (VB.NET examples).

The Delegate and its Wrapper

Jumping straight into code, the first thing needed is a vanilla delegate; parameterless and void. Next is a class which holds a delegate - we can't pass delegates in the way I'd like because they don't derive from Object so I’m sort of wrapping it up in a class which can be passed around.

delegate void UIWorkDelegate();

/// <summary>
/// Wraps a delegate in a class so the class can be passed to methods
/// only accepting type Object.
/// </summary>
class UIWorkWrapper
{
    public UIWorkWrapper(UIWorkDelegate work)
    {
        this.UIWork = work;
    }

    public UIWorkDelegate UIWork { get; set; }
}
Setting-up and Calling BackgroundWorker

To kick off the concurrent logic, we need to add some code somewhere in a method on the UI thread, either in a Window or some helper class. I’ve kept some extraneous code around to give it some context.

public partial class Window1 : Window 

    public Window1() 
    { 
        try 
        { 
            InitializeComponent(); 
        } 
        catch (Exception e) 
        { 
            System.Diagnostics.Debugger.Break(); 
        } 
    } 

    void StartSyncManager() 
    { 
        BackgroundWorker syncWorker = new BackgroundWorker(); 
        syncWorker.WorkerReportsProgress = true
        syncWorker.WorkerSupportsCancellation = true

        syncWorker.DoWork += new DoWorkEventHandler(syncWorker_DoWork); 
        syncWorker.ProgressChanged += new ProgressChangedEventHandler(syncWorker_ProgressChanged); 

        VolatileState.Synchroniser = new SyncManager(); 

        syncWorker.RunWorkerAsync(); 
    } 

    void syncWorker_DoWork(object sender, DoWorkEventArgs e) 
    { 
        VolatileState.Synchroniser.StartSynchLoop(syncWorker, new ViewModel(this)); 
    } 

    void syncWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) 
    { 
        var w = (UIWorkWrapper)e.UserState; 
        w.UIWork.Invoke(); 
    } 

    private void Start_Click(object sender, RoutedEventArgs e) 
    { 
        if (VolatileState.Synchroniser == null
        { 
            this.StartSyncManager(); 
            ((Button)sender).Content = "Stop"
        } 
        else 
        { 
            VolatileState.Synchroniser.Stop();
            VolatileState.Synchroniser = null;  
            ((Button)sender).Content = "Restart"
        } 
    } 
}

The VolatileState object is a hang-over from my test code so ignore it and pretend its says 'this' and points to a property on the Window1 class or something.

Interesting thing number 1: The DoWork method calls the StartSyncLoop method on the SyncManager passing in the BackgroundWorker that’s hosting it and a ViewModel which in turn has a constructor which points to the page we’re on. If we’re relying on data binding to do everything then we don’t need to pass a reference to our window, we just need a ViewModel instance with all the right bindings. My example uses an explicit UI control manipulation because its more obvious.

Interesting thing number 2: The ProgressChanged event handler method casts the UserState property of the event args back to a UIWorkWrapper and then invokes the delegate its wrapping!

The Synchroniser Thingy Class

If you haven't guessed by now, to get into the spirit of asynchronous activity I’m using a hypothetical example of a synchronisation loop which might keep an application in synch with a web service or something. The premise being that this method is called by the DoWork event handler code and so will begin its duties on another thread (note that thread-pool threads are actually supposed to be used for short bursts of work and not long-running background synch maintenance type tasks... but I won’t tell anyone if you won’t).

public void StartSynchLoop(BackgroundWorker worker, ViewModel viewModel)
{            
    while (!_worker.CancellationPending)
    {
        int t1 = Thread.CurrentThread.ManagedThreadId; 
        worker.ReportProgress(
            0,
            new UIWorkWrapper(
                delegate
                {
                    viewModel.Status = "Synchronizing...";
                    viewModel.PostStatusMessage(String.Format("Outside tid {0}, this code tid {1}.", t1, Thread.CurrentThread.ManagedThreadId));
                })
            );
        
        ... // synch code.

And that’s it. The asynchronously running loop can modify the ViewModel directly via an anonymous method delegate which will be run on the UI thread - note how the variables flow right through. The Status property could be data-bound and the PostStatusMessage could do something like this (this.Control having been set in the constructor to the Window1 instance):

public void PostStatusMessage(string message)
{
    ((Window1)this.Control).MainListBox.Items.Add(message);            
}

Thanks and good day to you.

Labels: , ,

Using Delegates; An "Oh for F**** sake" moment

Monday, May 11, 2009 / Posted by Luke Puplett / comments (3)

"Stay away from the nice doggy, children."

While reading the excellent (if somewhat late) Concurrent Programming on Windows: Architecture, Principles, and Patterns (Microsoft .Net Development) I began trying to recall the countless times that I have taken advantage of the framework's APM methods you get for free when you new up a delegate. Here's the noteworthy passage from page 418:

All delegate types, by convention, offer a BeginInvoke and EndInvoke method alongside the ordinary synchronous method. While this is a nice programming model feature, you should stay away from them wherever possible. The implementation uses remoting infrastructure that imposes a sizeable overhead...

Joe's choice of the word nice being a colloquial English word meaning not nice, shit, a poor effort. The scarcity of information from reliable sources and the arguments and proliferation of inaccuracies in the area of concurrency in .NET had me guessing that Joe's book would contain some nasty surprises which is why I'm somewhat peaved that such an important reference has only just come available, eight years after the Framework was released - and two years into my own person journey of asynchronous discovery! --grrrr.

Labels: , , ,