Click here to Skip to main content
15,886,075 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I'm fairly new to background workers, but I understand the gist of their use. I'm writing a program to update ID3 tags in MP3 files, ensuring that the title and artist fields match what is in the filename. I have a form that accepts some user input regarding which folders to process and files to exclude. The form has a tab control, with the first tab accepting the basic settings, the second tab accepting advanced settings, and the third displaying a list box that tracks the files that have been processed (or skipped) so far. The form has a status strip which contains both a label and a ProgressBar. I'm using the worker's ProgressChanged event to update the ProgressBar and ListBox (passing in messages to be dispatched to both in the ProgressChangedEventArgs.UserState). It's important to note that while processing is underway, *only* the ProgressChanged event is updating that ListBox. The updates happen just fine. The program can run to the end of the folder list and not have any issues.

The problem occurs if I click on the tab displaying the ListBox during processing. I immediately receive an invalid cross-thread operation exception. I'm not doing anything in code to conjure this exception up; it seems to be happening as soon as the control draws itself. (For this reason, it seems redundant to include code samples, but I certainly can add to this if requested. I'm hoping this is more of a conceptual matter, something I'm overlooking about how threading works. There are many routines in the form, and any of them could be underway when the user switches tabs.) The exception is thrown in the DoWork event handler.

No other control on the form causes this kind of headache. I can switch between the other tabs just fine. I've tried swapping out the ListBox for a RichTextBox, but the same thing happens. I've worked around it for the time being by disabling the tab control so that the user can't switch to the ListBox, but that defeats the ListBox' purpose, and also eliminates some of the form's hard-won responsiveness.

Since none of my (presumed) relevant code is executing when the exception is thrown, I'm stuck for a place to set a breakpoint. Is there a way to override the ListBox' behavior so that simply making it visible doesn't provoke this error condition? The only event I can think of that might possibly be of use is VisibleChanged, which I've confirmed is raised when the tab is switched.

What I have tried:

private void Worker_ProgressChanged(object Sender, ProgressChangedEventArgs E)
{
    try
    {
        ProgressState state = (ProgressState)E.UserState;

        if (tagMode == TagModeEnum.TagMultipleFiles || tagMode == TagModeEnum.TagMultipleFolders)

            proBar.Value = filesProcessed;

        //  update listbox and status bar label
        if (state != null)
        {
            lstStatus.Items.Add(state.ListBoxMessage);
            if (options.LogProgress)
            {
                //  code to update log files
            }
            //  etc., etc.
        }
    }
    catch
    {
    }
}
Posted
Updated 4-Aug-21 19:20pm

1 solution

Without seeing the relevant code it is difficult to say anything ...
But :
Cross-Thread-Execption means that you directly access a Control from your Worker.
All the Controls belong to the "Main-Thread" of the UI - that means that a Control only has this "Master".
If you want to do something with a Control from a Worker you have to use the Invoke-Functionality ...
 
Share this answer
 
Comments
Maciej Los 5-Aug-21 2:30am    
5ed!
Ralf Meier 5-Aug-21 3:11am    
Thanks Maciej :)
byff 5-Aug-21 11:25am    
Makes sense. I'll update and see how things work. Thank you!
byff 5-Aug-21 11:55am    
Groovy. I took the approach described here, and it's working great. Thanks again.

https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.control.invoke?view=net-5.0

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900