Search code examples
vb.netmultithreadinglistboxbackgroundworker

Do I need a delegate to read while using a background worker?


I am using a background worker for an app that reads through thousands of files and searches for certain text. It's basically to find out what accounts are part of account groups, so I'm searching the entire group directory via a loop in a background worker.

I have delegate subs setup to update label text and to add items to listboxes, and it seems to have cleared up any issues I had about illegal threading. However, I'm not finding specific details about reading through listboxes, for example. So for instance, if I find the account inside of a group but that group has already been added to my listbox, I don't want to add it again or else it will be a duplicate.

My program is working fine - but from what I've read threading doesn't always throw an error right away. I'm trying to avoid rolling my app out and having the error come up sporadically. So my question is: do I need a delegate to READ a listbox too?


Solution

  • Just as a little terminology note: Delegates are merely pointers to other methods and do not provide any thread-safety at all themselves. What you are doing is called invoking methods on the UI thread (or just invoking, for short).

    To answer your question: The best practice is to always invoke when accessing UI elements from a background thread. UI elements (controls) should never be accessed from a background thread because the User Interface cannot handle cross-thread calls, since there's a great chance of concurrency (that is, when two threads try to access the same control at the same time).

    When the .NET runtime detects a call to a control from another thread than the control was created on it throws an InvalidOperationException. It does this in order to prevent you from doing something that could potentially break the application. This detection works rather good, but it's not perfect.

    In some cases the runtime doesn't detect that you're performing an illegal cross-thread call, in which case it will not throw an exception. Your application still works, but that doesn't exclude the fact that there can still be concurrency issues.

    For instance, if you were to add or remove items from the ListBox from the UI thread, while at the same time running a heavy loop over the list box items from the background thread then that would cause your application to break and the loop will most likely throw an exception.

    To summarize: You can access some control properties without the .NET runtime throwing an InvalidOperationException, but if the property is something that affects the control's behaviour/look/contents then the best practice is to always invoke to avoid any concurrency issues.