@bobnoordam

Update a winforms control from a background thread

This is the absolute minimum you need to update a control on the GUI thread from a background thread. The key here is the line

Invoke(new Action<int>(UpdateGuiText), result);

Which will invoke an update on the GUI thread from another thread. The interface consists of a single button and a single textbox. Each click on the button launches a new thread with an endless loop which will randomly update the textbox by Invoking the update procedure for the GUI thread. You will notice that it is possible to click multiple times and see the action speed up in the textbox, without the GUI getting clogged.

using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
 
namespace TaskDelegate
{
    public partial class Form1 : Form
    {
        private readonly Random _random;
 
        public Form1()
        {
            InitializeComponent();
            _random = new Random();
        }
 
        /// <summary>
        ///     Start a background thread, which does not block the GUI thread
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonStartTask_Click(object sender, EventArgs e)
        {
            Task t = Task.Factory.StartNew(() => DoWork(_random));
        }
 
        /// <summary>
        ///     In an endless loop, wait a random number of milliseconds and then invoke an update
        ///     of the control on the GUI thread.
        /// </summary>
        /// <param name="random"></param>
        private void DoWork(Random random)
        {
            while (true)
            {
                int result = random.Next(1000);
                Thread.Sleep(result);
                Invoke(new Action<int>(UpdateGuiText), result);
            }
        }
 
        /// <summary>
        ///     Update the control on the GUI thread. (Called from the background thread)
        /// </summary>
        /// <param name="result"></param>
        private void UpdateGuiText(int result)
        {
            textBoxResults.Text = result.ToString();
        }
    }
}