2

I have a Windows Form, which is a modal mdi child, that is suppose to be shown when some intense background work is going on, so the user cannot use any of the controls until that work is finished.

It is very simple, here is the code.

public partial class ProgressForm : Form
{
    private int periodCount = 5;

    public ProgressForm(String message)
    {
        InitializeComponent();
        messageLabel.Text = message;
    }

    public void startThread()
    {
        Thread t = new Thread(new ThreadStart(doWork));
        t.IsBackground = true;
        t.Start();
    }

    void doWork()
    {
        while (true)
        {
            if (periodCount == 5)
            {
                periodCount = 1;
            }
            else
            {
                periodCount++;
            }

            switch (periodCount)
            {
                case 1: periodsLabel.Text = "."; break;
                case 2: periodsLabel.Text = ". ."; break;
                case 3: periodsLabel.Text = ". . ."; break;
                case 4: periodsLabel.Text = ". . . ."; break;
                case 5: periodsLabel.Text = ". . . . ."; break;
            }
        }
    }
}

but, the periodsLabel.Text does not change as it is suppose to! How do I get it to update the UI while doing something else in the background?

ProgressForm progressForm = new ProgressForm("Your database data is being exported, please wait.");
progressForm.ShowDialog();
progressForm.startThread();
CODe
  • 2,253
  • 6
  • 36
  • 65
  • Do you have any exception details from these crashes? – Jay Dec 18 '10 at 05:22
  • The program simply stops responding. I thought this was a particularly neat way of doing things, but I suppose not. – CODe Dec 18 '10 at 05:23
  • +1 Multhreading debutes are always a pain for anyone who starts using it. Any useful information is then welcome for the ones who didn't yet come through. =) – Will Marcouiller Dec 18 '10 at 05:59

2 Answers2

2

First, in my humble opinion, you should not just throw away a thread like you do.

The best practice is using a BackgroundWorker Thread.

Second, you form isn't modal at all, as you only show it using the Show() method. In order to make it a modal form, you need to make it a dialog using the ShowDialog() method.

As to why exactly your Form is crashing is quite out of scope from now on. Please consider following the following steps:

  1. Instantiate a BackgroundWorker class;
  2. Make the BackgroundWorker.DoWork() method do the dirty work for you;
  3. Make sure you set the BackgroundWorker.WorkerReportsProgress = true in the component model property window in design;
  4. Make sure you ReportProgress() using the ReportProgress(int) method.

Please see this question (C#: Populating a UI using separate threads.) and my code sample which simply explains, I think, the use of a BackgroundWorker class instance.

Note: Still looking for another example.

EDIT #1

Here's a good article on threads: Threading in C#.
'Cause Jon Skeet said so! Multi-threading in .NET: Introduction and suggestions.

Community
  • 1
  • 1
Will Marcouiller
  • 23,773
  • 22
  • 96
  • 162
  • Keep in mind, if updating any controls while on a thread other than the thread the control was created on, you need to delegate back to the thread it was created on. Use Control.InvokeRequired to determine if this is the case and call Control.Invoke() if it is needed. Here is the msdn article on using Invoke: http://msdn.microsoft.com/en-us/library/a1hetckb.aspx – Brian Ball Dec 18 '10 at 05:45
  • Damnit, this stuff has always confused the hell out of me. – CODe Dec 18 '10 at 05:47
  • It doesn't take much to get over the learning curve of using threads. If you're using .NET 3.5 or later, you don't need to create a delegate, you can pass in a lambda function instead. – Brian Ball Dec 18 '10 at 05:48
  • Ah, can you link an article on that? I'll try to do some googling in the meantime to see if I can find something... – CODe Dec 18 '10 at 05:50
  • @Will: Thanks a lot for your input. I'll do some more research and testing and figure it out I'm sure. :) – CODe Dec 18 '10 at 06:23
  • @CODe: Have you been able to work your way along with the `BackgroundWorker` class and your *ProgressForm*? – Will Marcouiller Dec 19 '10 at 17:17
0

It's likely that your app is crashing because you are trying to access your form elements' properties directly from a thread (e.g. when you call PeriodsLabel.Text) rather than using BeginInvoke from your thread to call a method on your form which will do the property accessing.

But it's better/simpler to use the BackgroundWorker class for these kinds of things.

Tola Odejayi
  • 3,019
  • 9
  • 31
  • 46