John Gallagher
John Gallagher

Reputation: 6268

Should I use a background thread for my UI actions?

Background

Example

The whole tree looks like this:

Name                       Project              IsTrained
Users                      nil                  NO
  John                     nil                  NO              
    Documents              nil                  NO
      Acme Project         Acme Project         YES
        Proposal.doc       Acme Project         YES
          12:32-12:33      Acme Project         YES
          13:11-13:33      Acme Project         YES
          ... etc
        Budget.xls         Acme Project         YES
      Big Co Project       Big Co Project       YES
        Deadlines.txt      Big Co Project       YES
        Spec.doc           Big Co Project       YES
      New Project          nil                  NO
        StartingUp.doc     nil                  NO
      Personal Stuff       Personal             YES
        MyTreehouse.doc    Personal             YES
    Movies                 nil                  NO
      Aliens.mov           nil                  NO
      StepMom.mov          nil                  NO

And the NSOutlineView would only see this:

Users                      nil                  NO
  John                     nil                  NO              
    Documents              nil                  NO
      New Project          nil                  NO
        StartingUp.doc     nil                  NO
    Movies                 nil                  NO
      Aliens.mov           nil                  NO
      StepMom.mov          nil                  NO

If you assigned Movies to Personal, the view would now look like this:

Users                      nil                  NO
  John                     nil                  NO              
    Documents              nil                  NO
      New Project          nil                  NO
        StartingUp.doc     nil                  NO

Code

TrainingGroup.m

-(void)setProjectTopLevel:(JGProject *)projectToAssign {
    [self setProjectForSelf:projectToAssign];
    [self setProjectForChildren:projectToAssign];
}

-(void)setProjectForSelf:(JGProject *)projectToAssign {
    [self setProject:projectToAssign];
}

-(void)setProjectForChildren:(JGProject *)projectToAssign {
    for (TrainingGroup *thisTrainingGroup in [self descendants]) {
        [thisTrainingGroup setProject:projectToAssign];
        if(projectToAssign != nil) {
            [thisTrainingGroup setIsTrainedValue:YES];
        } else {
            [thisTrainingGroup setIsTrainedValue:NO];
        }
        // Other code updating rules.
    }
}

-(JGProject *)projectTopLevel {
    return [self project];
}

-(NSSet *)untrainedChildren {
    // Code that loops through all children returning those
    // whose isTrained is NO. Omitted for brevity.
}

The Problem

As you can see above, I'm running all the project assignment code on the main thread currently.

When there are hundreds of time entries under each folder, my app becomes unresponsive.

Possible Solutions

1 Modal progress bar

The Approach

The Good

The Bad

2 Non Modal Spinner

The Approach

The Good

The Bad

3 Hide

The Approach

Good and Bad

4 Improve performance

The Approach

The Good

The Bad

My Questions

As far as I can see, none of the options above are ideal.

1. Which is the best option?

2. Are there any other options?

3. What could I improve about my approach?

Upvotes: 2

Views: 165

Answers (1)

jrtc27
jrtc27

Reputation: 8526

  1. I would update on a background thread (No. 2)
  2. You could always disable user input on sections of your window, and display a loading message.
  3. Simple to say - go through all your code, and make sure you are making the least number of calls required, and that you do not call any unnecessary functions. You could also run some long lasting operations on separate threads, and then get notified when the action finishes, so you can process other things while the operation goes on.

Upvotes: 1

Related Questions