Who should handle threading in MVC? - multithreading

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?

I see two arguments for the Controller having the responsibility for Thread safety.
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.
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.

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 ?

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.

Related

Multithreaded GUI update() methods

I'm begginer in multithreading. I recently started to writing something like multithreaded observer. I need some clarification.
Let's say I'm working with Subject, and I'm changing its state. Then Observers (in example - GUI widgets) have to be notified, so they could perform the update() method.
And there is my question: how am i handling those getValue() performed by many Observers? If it's just a getter for some variable, do i have to run it in new thread? Does it require any locking?
Or mayby there is a metod to just send those new value to GUI thread, and letting widgets there access those value. And again, can it be a single loop, or do i have to create another threads for every widget to get those value?
That's a difficult subject. Here are couple of things that will guide and help you with it.
Embrace eventual consistency. When one object updates on one thread, others will receive change notifications and update to the correct state eventually. Don't try to keep everything in sync all the time. Don't expect everything to be up to date all the time. Design your system to handle these situations. Check this video.
Use immutability especially for collections. Reading and writing to a collection from multiple threads can result in disasters. Don't do it. Use immutable collections or use snapshotting. Basically one object that will called from multiple thread will return a snapshot of the state of the collection. when a notification for a change is received, the reader (GUI in your case) will request a snapshot of the new state and update it accordingly.
Design rich Models. Don't use AnemicModels that have only setters and getters and let others manipulate them. Let the Model protect it's data and provide queries for it's state. Don't return mutable objects from properties of an object.
Pass data that describes changes with change notifications. This way readers (GUI) may sync their state only from the change data without having to read the target object.
Divide responsibility. Let the GUI know that it's single threaded and received notifications from the background. Don't add knowledge in your Model that it will be updated on a background thread and to know that it's called from the GUI and give it the responsibility of sending change requests to a specific thread. The Model should not care about stuff like that. It raises notifications and let subscribers handle them the way they need to. Let the GUI know that the change notification will be received on the background so it can transfer it to the UI thread.
Check this video. It describes different way you can do multithreading.
You haven't shown any code or specified language, so I'll give you an example in pseudo code using a Java/C# like language.
public class FolderIcon {
private Icon mIcon;
public Icon getIcon() { return mIcon; }
public FolderIcon(Icon icon) {
mIcon = icon;
}
}
public class FolderGUIElement : Observer {
private Folder mFolder;
private string mFolderPath;
public FolderGUIElement(Folder folder) {
mFolder = folder;
mFolderPath = mFolder.getPath();
folder.addChangeListener(this);
}
public void onSubjectChanged(change c) {
if(c instanceof PathChange) {
dispatchOnGuiThread(() => {
handlePathChange((PathChange)change);
});
}
}
handlePathChange(PathChange change) {
mFolderPath = change.NewPath;
}
}
public class Folder : Subject {
private string mPath;
private FolderIcon mIcon;
public string getPath() { return mPath; }
public FolderIcon getIcon() { return mIcon; }
public void changePath(string newPath) {
mPath = patnewPath;
notifyChanged(new PathChange(newPath));
}
public void changeIcon(FolderIcon newIcon) {
mIcon = newIcon;
notifyChanged(new IconChange(newIcon));
}
}
Notice couple of things in the example.
We are using immutable objects from Folder. That means that the GUI elements cannot get the value of Path or FolderIcon and change it thus affecting Folder. When changing the icon we are creating a brand new FolderIcon object instead of modifying the old one. Folder itself is mutable, but it uses immutable objects for it's properties. If you want you can use fully immutable objects. A hybrid approach works well.
When we receive change notification we read the NewPath from the PathChange. This way we don't have to call the Folder again.
We have changePath and changeIcon methods instead of setPath and setIcon. This captures the intent of our operations better thus giving our model behavior instead of being just a bag of getters and setters.
If you haven't read Domain Driven Design I highly recommend it. It's not about multithreading, but on how to design rich models. It's in my list of books that every developer should read. On concept in DDD is ValueObject. It's immutable and provide a great way to implement models and is especially useful in multithreaded systems.

Monotouch PerformSelector on specific thread with multiple arguments and callbacks

I've been having some issues with threading in monotouch. My app makes use of an external library which I've linked with and it works fine. Because of the nature of the app and the library I have to make all the calls to it on a single separate thread.These calls will generally be :
Random non deterministic caused by user
Every t miliseconds(around 20ms). Like an update function
After reading for a bit I decided to try out NSThread. I've managed to call the Update function by attaching an NSTimer to the thread's RunLoop and it's all working fine. The problem that I'm having now is calling other methods on the same thread. I read somewhere that using PerformSelector on the RunLoop adds the selector invocation to the RunLoop's queue and invokes it when available, which is basically exactly what I need. However the methods that I need to call :
Can have multiple paramteres
Have callbacks, which I need to invoke on the main thread, again with multiple parameters
For the multiple parameters problem I saw that NSInvocation can be a solution, but the life of me I can't figure out how to do it with monotouch and haven't found any relevant examples.
For the actuals calls that I need to make to the library, I tried doing a generic way in which I can call any function I choose via delegates on a particular thread, which sort of works until I'm hit with the multiple parameters and/or callbacks to the main thread again with multiple parameters. Should I maybe just register separate selectors for each (wrapped)function that I need to call from the library?
I'm not hellbent on using this approach, if there is a better way I'm open to it, it's just that after searching for other options I saw that they don't fit my case:
GCD(not even sure I have it in monotouch) spawns threads on it's own whenever necessary. I need a single specific thread to schedule my work on
NSInvocationQueue(which uses GCD internally from what I read) does the same thing.
pThreads, seem overkill and managing them will be a pain(not even sure I can use them in monotouch)
I'm not an iOS developer, the app works fine with monodroid where I had Runnables and Handlers which make life easier :) . Maybe I'm not looking at this the right way and there is a simple solution to this. Any input would be appreciated.
Thanks
UPDATE
I was thinking of doing something along these lines :
Have a simple wrapper :
class SelectorHandler : NSObject
{
public static Selector Selector = new Selector("apply");
private Action execute;
public SelectorHandler(Action ex)
{
this.execute = ex;
}
[Register("apply")]
private void Execute()
{
execute();
}
}
Extend NSThread
public class Daemon : NSThread
{
public void Schedule(Action action)
{
SelectorHandler handler = new SelectorHandler(action);
handler.PerformSelector(SelectorHandler.Selector, this, null, true);
}
}
Then, when I want to call something I can do it like this :
private Daemon daemon;
public void Call_Library_With_Callback(float param, Action<int> callback)
{
daemon.Schedule(() =>
{
int callbackResult = 0;
//Native library calls
//{
// Assign callback result
//}
daemon.InvokeOnMainThread(() =>
{
callback(callbackResult);
});
});
}

Application Object Won't Share

I'm having issues with my Application Object. I am currently using a Service to simulate incoming data from an electronic game board. This data is represented as a 2D boolean array. Every five seconds the Service uses a method of the Application Object to update the array (setDetectionMap()). This array is being read by a Thread in my main Activity using another method (getDetectionMap()). After some debugging I am almost positive that the main Activity is not seeing the changes. Here is the code for my Application Object:
public class ChessApplication extends Application{
private static ChessApplication singleton;
private boolean[][] detectionMap;
public static ChessApplication getInstance(){
return singleton;
}
#Override
public void onCreate() {
super.onCreate();
singleton=this;
detectionMap=new boolean[8][8];
}
public boolean[][] getDetectionMap(){
return detectionMap;
}
public void setDetectionMap(boolean[][] newMap){
detectionMap=newMap;
Log.d("Chess Application","Board Changed");
}
}
I've checked my Manifest, I've rewritten my object declaration a dozen times, I've added LogCat tags to make sure that the code is executing when I think it should be, and I've even implemented the supposedly redundant Singleton code. Any ideas what could be causing this? Incidentally can anyone tell me how to view variable states as the activity is running? Thanks in advance.
Is your Activity calling getDetectionMap() to get the new map after the update occurs?
Because otherwise, it's holding onto a reference to the old boolean[][] array, wheras setDetectionMap(...) isn't actually updating the current data structure, it's just updating the "detectionMap" variable to point to a different one. As such, your main activity won't be aware of the swapout until the next time it calls getDetectionMap.
Easy fix: in setDetectionMap, manually copy values from newMap into detectionMap. Or, update the Activity's reference so it's looking at the right map.
One other observation entirely unrelated to the original question: It's quite unusual to override Application during Android development, and is usually considered a "code smell" unless you have a really good reason for doing so. In this case I imagine it's so that you can communicate between your service and Activity, but you create a middle-man where one isn't entirely necessary. Here's a useful SO thread on how to communicate directly between the two :)

BluetoothChat synchronized onResume Activity lifecycle method, why?

I'm studying right now the bluetooth Android API, and I ran into the BluetoothChat example.
http://developer.android.com/resources/samples/BluetoothChat/index.html
It contains many errors, first of all the simple fact that it uses API 11 but manifest does not force this minimum API.
Other interesting thing is the use of synchronized keyword on Activity lifecycle methods, like on onResume:
#Override
public synchronized void onResume() {
super.onResume();
if(D) Log.e(TAG, "+ ON RESUME +");
// Performing this check in onResume() covers the case in which BT was
// not enabled during onStart(), so we were paused to enable it...
// onResume() will be called when ACTION_REQUEST_ENABLE activity returns.
if (mChatService != null) {
// Only if the state is STATE_NONE, do we know that we haven't started already
if (mChatService.getState() == BluetoothChatService.STATE_NONE) {
// Start the Bluetooth chat services
mChatService.start();
}
}
}
Why this keyword is used there? Is there any reasonable explanation, or simply the one who wrote the code didn't know that onResume will be called always by the same thread? Or I miss something?
Thank you in advance!
This seems to be a pretty old question, but here's what I think may be going on:
My guess is that it wants to be careful about when "dialogs" return. The BluetoothChat example uses dialogs (as well as an overlay dialog-like activity) for enabling Bluetooth, enabling discovery, and initiating pairing/connections.
I don't know this for sure but I suspect there was a bug where different threads were returning to the main Activity and caused confusion as to how to handle onResume.
What they probably should have done is synchronize a block on an object and used flags to determine the state. That way the intention, state and functionality are more clear -- and the app knows what it should do in onResume;
something like this maybe:
//class fields
private Object myLockObj = new Object();
private boolean isPausedForPairing = false;
public void onResume()
{
super.onResume();
synchronized (myLockObj)
{
if (isPausedForPairing)
{
//handle a "pairing" onResume
}
}
}
However, due to it being an example app, they may have decided to go with something more simple. Example apps don't always follow convention because the idea is to demonstrate the particular code needed for the example. Sometimes following convention might add a lot of "distracting" code. Whether or not you agree with that is up to you though.

NInject and thread-safety

I am having problems with the following class in a multi-threaded environment:
public class Foo
{
[Inject]
public IBar InjectedBar { get; set; }
public bool NonInjectedProp { get; set; }
public void DoSomething()
{
/* The following line is causing a null-reference exception */
InjectedBar.DoSomething();
}
public Foo(bool nonInjectedProp)
{
/* This line should inject the InjectedBar property */
KernelContainer.Inject(this);
NonInjectedProp = nonInjectedProp;
}
}
This is a legacy class which is why I am using property rather than constructor injection.
Sometime when the DoSomething() is called the InjectedBar property is null. In a single-threaded application, everything runs fine.
How can this be occuring and how can I prevent it?
I am using NInject 2.0 without any extensions, although I have copied the KernelContainer from the NInject.Web project.
I have noticed a similar problem occurring in my web services. This problem is extremely intermittent and difficult to replicate.
First of all, let me say that this is wrong on so many levels; the KernelContainer was an infrastructure class kept specifically to work around certain limitations in the ASP.NET WebForms page lifecycle. It was never meant to be used in application code. Using the Ninject kernel (or any DI container) as a service locator is an anti-pattern.
That being said, Ninject itself is definitely thread-safe because it's used to service parallel requests in ASP.NET all the time. Wherever this NullReferenceException is coming from, it's got little if anything to do with Ninject.
I can think of two possibilities:
You have to initialize KernelContainer.Kernel somewhere, and that code might have a race condition. If something tries to use the KernelContainer before the kernel is fully initialized (possible if you use the IKernel.Bind methods instead of loading modules as per the guidance), you'll get errors like this. Or:
It's your IBar implementation itself that has problems, and the NullReferenceException is happening somewhere inside the DoSomething method. You don't actually specify that InjectedBar is null when you get the exception, so that's a legitimate possibility here.
Just to narrow the field of possibilities, I'd eliminate the KernelContainer first. If you absolutely must use Ninject as a service locator due to a poorly-designed legacy architecture, then at least allow it to create the dependencies instead of relying on Inject(this). That is to say, whichever class or classes need to create your Foo, have that class call kernel.Get<Foo>(), and set up your kernel to Bind<Foo>().ToSelf().

Resources