Search code examples
c#winformsmodal-dialogtask-parallel-librarybackgroundworker

Converting BackgroundWorker to Task.Run with a Modal Display


I've been learning about the features in the TPL Library. I came across an article from Stephen Cleary which compares the BackgroundWorker and Task.Run. I'm fairly comfortable with TPL and decided to convert some BackgroundWorker code to Task.Run in my WinForm application but I've not been able to figure the Task.Run equivalent for a particular situation. Essentially, I display a modal form while the long running operation is running in the BackgroundWorker, the purpose being to disallow the user from doing anything while also ensuring the app doesn't hang. Upon completion, the modal form is closed programmatically. I whipped up a quick example using BgWorker. Here's the main form:

public partial class Form1 : Form
{
        FrmMessageBox frm_ = new FrmMessageBox();
        BackgroundWorker worker_ = new BackgroundWorker();

        public Form1()
        {
            InitializeComponent();
            worker_.DoWork += (_, __) =>
            {
                Thread.Sleep(10000);
            };

            worker_.RunWorkerCompleted += (_, __) =>
            {
                    frm_.Close();
            };
        }

        private void button1_Click(object sender, EventArgs e)
        {
            worker_.RunWorkerAsync();
            ShowMessageBox();
        }

        private void ShowMessageBox()
        {
            frm_.Show("We're delaying 10 secs!", "Delay");
        }

        private void CloseMessageBox()
        {
            frm_.Close();
        }
    }

Here's the FrmMessageBox class:

public partial class FrmMessageBox : Form
    {
        public FrmMessageBox()
        {
            InitializeComponent();

        }

        public DialogResult Show(string message, string title)
        {
            Text = title;
            label1.Text = message;
            return ShowDialog();
        }
    }

When I click the button on the main form, the BgWorker kicks off and the modal form displays. Once the BgWorker is done, the form is closed in the completed event. Is there a way to get this same behavior with Task.Run?


Solution

  • Try this code

    private void button1_Click(object sender, EventArgs e)
    {
        Task.Run(() =>
        {
            Thread.Sleep(2000);
            Invoke(new Action((CloseMessageBox));
        });
    
        ShowMessageBox();
    }