WinForms Port message handling

Interaction with WinForms controls in asynchronous programs is not always straightforward. If you want to access a control from a background thread you might need to first switch to the Windows main thread (or the thread on which the control had been created) by calling Invoke() on the control or form. That´s not difficult to manage - but it´s cumbersome and adds noise to your code.

With a little help from the AppSpace it´s much easier, though. You won´t even see a difference between regular event handlers and Port message handlers. Here´s how you register a message handler for interaction with WinForms controls:

class MyForm : Form
{
    private Port<int> progressNotifications= ...;

    void MyForm(XcoAppSpace space)
    {
        Initialize();
        ...
        space.Receive(this.progressNotifications, OnProgress, SyncContext.UseCurrentSyncContext)
        ...
    }
    ...
    void OnProgress(int progress)
    {
        this.lblProgress.Text = progress.ToString();
    }
}
You bind a message handler to a Port using the XcoAppSpace extension method Receive<>() as usual. But this time you pass in SyncContext.UseCurrentSyncContext for a third parameter. This will wire up the message handler so that it gets called on the same thread as you call Receive<>().

You´re done. The message handling routine can freely access all controls on the form.

Last edited Feb 22, 2010 at 4:02 PM by thomass, version 4

Comments

RBisch Aug 24, 2010 at 5:43 PM 
Does the thread marshaling work the same on WPF ? Maybe a WPF example in the future.