1
\$\begingroup\$

I want to write my own Work-In-Progress form to use it throughout my app (for the time being, mostly as an exercise).

I came up with the following code, I would like to know what are the design issues, if this is not the way to go, if it could be simpler or more generic.

Main form:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    delegate void InvokeMethodDelegate(ProgressBar pb, Label status, string statusText);

    private void button1_Click(object sender, EventArgs e)
    {
        var frmWorking = new Form3();

        var wds = new WorkingDialogSettings("Working...", 1, 1, 1, 10, /*async*/ (pb) => 
        {
            for (long i = 0; i < 10; i++)
            {

                doWork(frmWorking.ProgressBar, frmWorking.Label, $"Progress step {i + 1}");
                Thread.Sleep(TimeSpan.FromSeconds(1));
                //if I use await the task immediately completes, using thread sleep blocks it till completion
                //await Task.Delay(TimeSpan.FromSeconds(1));
            }

        });
        frmWorking.ShowDialog(wds);
    }

    private async void doWork(ProgressBar pb, Label status, string statusText)
    {
        if (pb.InvokeRequired || status.InvokeRequired)
        {
            pb?.Invoke(new InvokeMethodDelegate(doWork), pb, status, statusText);
            return;
        }

        pb.PerformStep();
        await Task.Delay(TimeSpan.FromSeconds(0.5));
        status.Text = statusText;
    }
}

Work-In-Progress form:

 public partial class Form3 : Form
{
    public Label Label { get { return label1; } }
    public ProgressBar ProgressBar { get { return progressBar1; } }

    private WorkingDialogSettings _wds;
    public Form3()
    {
        InitializeComponent();
    }

    private void Form3_Load(object sender, EventArgs e)
    {
        Task.Run(() => 
        {
            _wds.ProgressBarAction(ProgressBar);
        }).ContinueWith((t) => 
        {
            if (t.Status == TaskStatus.RanToCompletion)
            {
                Label.Text = "*** COMPLETED ***";
                Cursor = Cursors.Default;
            }
        });

    }

    public void ShowDialog(WorkingDialogSettings workingDialogSettings)
    {
        _wds = workingDialogSettings;
        ProgressBar.Minimum = workingDialogSettings.Minimum;
        ProgressBar.Maximum = workingDialogSettings.Maximum;
        ProgressBar.Step = workingDialogSettings.Step;
        ProgressBar.Value = workingDialogSettings.Value;
        this.Text = workingDialogSettings.Title;

        this.ShowDialog();
    }
}

public class WorkingDialogSettings
{
    public WorkingDialogSettings(string title, int step, int value, int minimum, int maximum, Action<ProgressBar> progressBarAction, List<string> statuses = null)
    {
        Title = title;
        Step = step;
        Value = value;
        Minimum = minimum;
        Maximum = maximum;
        ProgressBarAction = progressBarAction;
        Statuses = statuses;
    }

    public string Title { get; private set; }
    public int Step { get; private set; }
    public int Value { get; private set; }
    public int Minimum { get; private set; }
    public int Maximum { get; private set; }
    public IEnumerable<string> Statuses { get; private set; }

    public Action<ProgressBar> ProgressBarAction { get; private set; }


}

Any corrections, suggestions, remarks ?

\$\endgroup\$
  • 1
    \$\begingroup\$ That code in Form3_Load should use a BackGroundWorker in WinForms. It synchronizes thread scheduling for you. \$\endgroup\$ – dfhwze Aug 26 at 9:13
  • \$\begingroup\$ @dfhwze would you nowadays still use that ancient thing? \$\endgroup\$ – t3chb0t Aug 26 at 9:25
  • \$\begingroup\$ @t3chb0t It's consistent with the archaic technology called WinForms :p \$\endgroup\$ – dfhwze Aug 26 at 9:27
  • \$\begingroup\$ @t3chb0t: as I said, this came out as an exercise \$\endgroup\$ – Veverke Aug 26 at 9:28
  • 2
    \$\begingroup\$ Check out this post what ContinueWith requires to post back to UI: codeproject.com/Articles/1018071/ContinueWith-Vs-await. That being said, async/await is the de facto standard these days \$\endgroup\$ – dfhwze Aug 26 at 9:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.