Jarrett Phillips Jarrett Phillips - 2 months ago 21
C# Question

ProgressBar disappears when changed from within a thread

Why does the progress bar disappear when the style is changed from within a thread and how can I avoid having this happen?

I have a thread that runs for an indeterminate (but potentially lengthy) amount of time, so I wanted to use the progress bar to track the thread's progress. I set the progress bar style to marquee before starting the thread to start, however once the thread finishes and sets the progress bar style back to blocks (which you can do from another thread by setting Form.CheckForIllegalCrossThreadCalls = false) the progress bar disappears from the form visually. Additionally, if I put a button on my form for the express purposes of changing the progress bar style back and forth, it will reappear, and change style back and forth as the button is pressed successively.

Answer

Woah there! Stay the heck away from CheckForIllegalCrossThreadClass. That property, while Microsoft made it available and I'm sure there is a very, very, very rare (and I mean rare) use for it, don't ever touch it. It will literally bring your software harm.

You can use a simple ISyncronizeInvoke approach to update your UI, which I also wrote a blog post on (very simple one).

/// <summary>
/// Helper class that allows synchronized invoking to be performed in a single line of code.
/// </summary>
internal static class SynchronizedInvoke {
    /// <summary>
    /// Invokes the specified action on the thread that the specified sync object was created on.
    /// </summary>
    public static void Invoke(ISynchronizeInvoke sync, Action action) {
        if (!sync.InvokeRequired) {
            action();
        }
        else {
            object[] args = new object[] { };
            sync.Invoke(action, args);
        }
    }
}

The usage is easy.

private void MyThreadWork() {
    // Do some work
    SynchnronizeInvoke.Invoke(uxProgressBar, () => uxProgressBar.Style = ProgressBarStyles.Blocks);
}