Windows Forms or WPF UI updates from a different thread #coding #programming #csharp

OK, we’ve all wanted to update the UI from a different thread at some point, it is annoying, that damn exception you get…
System.InvalidOperationException
{“Cross-thread operation not valid: Control ‘listBox1’ accessed from a thread other than the thread it was created on.”}

I tend to come back to the same approach time and time again, there may be others, but here’s an example I knocked up for a friend because this is easier to read than explain over the phone, upon clicking button1 I want to add some text to listBox1 without locking up the UI:

        private static void LogToList(SynchronizationContext ctx, ListBox listBox, String text)
        {
            ctx.Post((t) => { listBox.Items.Add(t); }, text);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Task.Factory.StartNew((ctx) =>
            {
                for (int i = 0; i < 10; i++)
                {
                    LogToList((SynchronizationContext)ctx, listBox1, DateTime.Now.ToString());
                    Thread.Sleep(1000);
                }
            }, (Object)SynchronizationContext.Current);
        }

For those who haven’t used it before, Task was introduced in .NET 4 under what is known as the Task Parallel Library (TPL), from what I can tell it is seen as the replacement for BackgroundWorker, but there’s no reason why you can’t do the same with a BackgroundWorker as we did before .NET 4.

In WPF I’ve previously also used System.Windows.Threading.Dispatcher.BeginInvoke in a similar-ish way. To get the Dispatcher instance, what you want is System.Windows.Application.Current.Dispatcher.

This also reminds me that if you’re doing a lot of logging / updating of a control then setting UndoLimit to zero is a good thing if you don’t want to leak / consume what can be vast amounts of memory for an undo buffer you don’t want or need.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s