Results 1 to 7 of 7

Thread: New to multithreading - help required

  1. #1

    Thread Starter
    Lively Member
    Join Date
    Sep 2008
    Location
    Scotland
    Posts
    68

    New to multithreading - help required

    Good afternoon fellow forumites

    I've been coding in VB on and off for the last ten years, but I've only now identified a requirement for multi-threading in my Windows Forms project.

    I'm in the process of building a new application which makes it possible for the end-user to run a variety of different file imports. The application contains a single form which itself contains a combo box, a button, a multi-line text box and two progress bars.

    The combo box enables the user to select the import that s/he wants to run, and the button enables him/her to then go ahead and run that import. The multi-line text-box is used to provide the user with feedback on what is actually happening at that particular point, whilst the two progress bars provide a graphical representation of how far the process has gone - the first progress bar tracks lets the user see how many files have been/have still to be processed while the second progress bar tracks the progress within the current file.

    Each of the import processes is coded into a separate module, thus making it easier for me to isolate and troubleshoot any issues (as well as making the code much easier to read). The status text-box and progress bars are updated using a further separate Functions module, with the various functions being called at the appropriate points.

    Whilst testing some of the larger modules, I started receiving a series of Managed Debugging Assistant exceptions being called. From memory, the majority of these were DisconnectedContext breaks - when I did some reading on these, everything I read seemed to suggest that the breaks were being caused by the fact that everything is being done on a single thread and therefore the UI isn't being refreshed often enough.

    I've managed to work out how to have a particular module called within a thread, but as soon as I do that, I lose the functionality that provides either textual or graphical feedback to the end-user. Therefore, I need to understand how I code the calls to the functions that update the status box and progress bars so that the user is getting the feedback that s/he would want. At this point I should reiterate that I have never worked with multiple threads before, so the terminology is all very bewildering at the moment.

    If anyone can give me any pointers on this, I'll be more than grateful.

    TIA


    Ian Henderson

  2. #2
    Super Moderator FunkyDexter's Avatar
    Join Date
    Apr 2005
    Location
    An obscure body in the SK system. The inhabitants call it Earth
    Posts
    7,957

    Re: New to multithreading - help required

    I'm not a great multi-threader but the way I've seen this done is to wrap your modules into "thread classes". the thread classes expose events "progress" events which are fired each time a thread carries out a bit of work. The form/module/whatever that fires off the threads can then consume those events and provide feedback to the user.

    I think that might be a bit "old school" though and it wouldn't surprise me to hear that there are better ways nowadays.
    The best argument against democracy is a five minute conversation with the average voter - Winston Churchill

    Hadoop actually sounds more like the way they greet each other in Yorkshire - Inferrd

  3. #3

    Thread Starter
    Lively Member
    Join Date
    Sep 2008
    Location
    Scotland
    Posts
    68

    Re: New to multithreading - help required

    Quote Originally Posted by FunkyDexter View Post
    I'm not a great multi-threader but the way I've seen this done is to wrap your modules into "thread classes". the thread classes expose events "progress" events which are fired each time a thread carries out a bit of work. The form/module/whatever that fires off the threads can then consume those events and provide feedback to the user.

    I think that might be a bit "old school" though and it wouldn't surprise me to hear that there are better ways nowadays.
    Thanks FunkyDexter

    Please excuse what might turn out to be a silly question, but how do I wrap up those modules? For example, on my main form, the code behind the button fires a CASE statement which looks to see which value has been selected in the combo box and executes the main method in the appropriate module.

    For most of those selections, the case statement simply fires moduleName.methodName(). As an experiment, I tried changing that for one of the case selections so that it looks like this:

    dim ThreadName = New Thread (AddressOf moduleName.methodName)
    ThreadName.IsBackground = True
    ThreadName.Start()

    On the face of this, this approach works a treat. However it's providing absolutely no feedback to the user which will ultimately alarm them because they'll think the process isn't actually doing anything. The only thing that will change when the code is running is the fact that the button disappears - I decided to hide the button until the user had made a selection in the combo box and the code for handling the visibility of the button appears at the bottom of the Click event because the intention is that it would be the last thing to be done.

  4. #4
    PowerPoster Evil_Giraffe's Avatar
    Join Date
    Aug 2002
    Location
    Suffolk, UK
    Posts
    2,555

    Re: New to multithreading - help required

    This is the exact scenario for which BackgroundWorkers were provided. I would look into those before handling the threading yourself.
    Last edited by Evil_Giraffe; May 11th, 2015 at 08:28 AM.

  5. #5
    Super Moderator FunkyDexter's Avatar
    Join Date
    Apr 2005
    Location
    An obscure body in the SK system. The inhabitants call it Earth
    Posts
    7,957

    Re: New to multithreading - help required

    I don't have a VB example to hand but here's some code I've cribbed from a C#. Hopefully it'll point you in the right direction.

    Create a "thread class" to do the work. This will need to inherit from BackgroundWorker:-
    Code:
    internal class GeneratePredictionsThread : BackgroundWorker
    Have it override the OnDoWork method. this is what will fire when you kick the thread off:-
    Code:
    protected override void OnDoWork(DoWorkEventArgs e)
            {
                try
                {
                    base.OnDoWork(e);
                    //do your work here.  In your case that's probably a matter of calling the methods you've already written
                }
                catch (Exception exc)
                {
                    exceptions.Add(exc);
                }
            }
    You call the ReportProgress Method (inherited from BackGroundWorker) to report that your thread has made progress:-
    Code:
    ReportProgress(percentComplete)

    So that's how you wrap your method and have it report progress back to the consumer. Now let's look at the consumer. First create an instance of your wrapper to do some work:-
    Code:
    using (generatethread = new GeneratePredictionsThread())
    {
    ... //following snippets go here
    }
    Subscribe to the events your wrapper is going to generate when it reports progress:-
    Code:
                        generatethread.ProgressChanged += new ProgressChangedEventHandler(t_ProgressChanged);
                        generatethread.RunWorkerCompleted += new RunWorkerCompletedEventHandler(t_RunWorkerCompleted);
    Then kick off the thread:-
    Code:
    generatethread.RunWorkerAsync();
    That will set your thread running. Whenever you issue a ReportProgress from within the thread class it will fire the ProgressChanged Event Handler (including the percentage complete in the event args) and when it completes it will automatically fire the RunWorkerComplete event.

    Apologies for the C#. Hopefully another member will be able to provide a more readable VB version but I'm afraid I don't have one available. It also wouldn't surprise me to learn that there are better ways to do this now as this was written some time ago.
    The best argument against democracy is a five minute conversation with the average voter - Winston Churchill

    Hadoop actually sounds more like the way they greet each other in Yorkshire - Inferrd

  6. #6
    Super Moderator FunkyDexter's Avatar
    Join Date
    Apr 2005
    Location
    An obscure body in the SK system. The inhabitants call it Earth
    Posts
    7,957

    Re: New to multithreading - help required

    Here's a tutorial Pradeep wrote in VB. It should be a lot easier to follow than my C# example.
    The best argument against democracy is a five minute conversation with the average voter - Winston Churchill

    Hadoop actually sounds more like the way they greet each other in Yorkshire - Inferrd

  7. #7
    PowerPoster stanav's Avatar
    Join Date
    Jul 2006
    Location
    Providence, RI - USA
    Posts
    9,290

    Re: New to multithreading - help required

    You also may want to look at using a custom DataGridView or ListView to display the threads' progress (you add a new row dynamically when a new thread is spun off)
    Let us have faith that right makes might, and in that faith, let us, to the end, dare to do our duty as we understand it.
    - Abraham Lincoln -

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width