Who should handle threading in MVC?

2019-02-25 03:51发布

问题:

Long-running tasks are usually executed in a background thread to keep the UI from freezing. It seems the threading logic could reside in either the view or in the controller.

As an example (in C#), suppose there is a method named RunAsync that runs a delegate in a background thread, here are two ways of doing it:

// Option 1

public class View {
  public void OnButtonClicked() {
    RunAsync(() => controller.DoSomething());
  }
}

public class Controller {
  public void DoSomething() {
    model.Foo();
  }
}

or:

// Option 2

public class View {
  public void OnButtonClicked() {
    controller.DoSomething();
  }
}

public class Controller {
  public void DoSomething() {
    RunAsync(() => model.Foo());
  }
}

Is there an advantage to doing it one way or the other?

回答1:

I see two arguments for the Controller having the responsibility for Thread safety.

  1. The controller is (at least conceptually) reusable by many views. We avoid repeating ourselves but putting the RunAsync() in the Controller rather than in many Views.
  2. Only the Controller really "knows" whether any such threading is needed. Indeed we might change the controller in future. So we have a "single responsibility" way of thinking. The controller both decides whether RunAsynch() is needed and actualy makes sure it is done.


回答2:

My understanding is Controller( or ViewModel in WPF) should handle this. View is always intended to be coupled with 'VIEW' related stuffs, thus tasks like running background job should go to controllers.

doesn't that sound odd to you that VIEW should handle this logic ?



回答3:

In my opinion, it should be handled by the Controller. Since you want to separate the Model from the View as much as possible, really the View should have no idea that a particular call such as model.Foo() takes a long time and therefore needs to be run asynchronously. The Controller on the other hand is the only one that really has knowledge of both, and therefore should make the decision on whether some operation needs to run asynchronously.