Why MvxCachingFragmentCompatActivity call ExecutePendingTransactions manually? - performance

Use mvvmcross for Xamarin.Android. Why MvxCachingFragmentCompatActivity call ExecutePendingTransactions in ShowFragment method manually? What actions done with this call? As I see, it can takes about second for several devices while navigation.
Thanks

It is basically necessary, if the next actions rely on the handling of the commit() before doing any other action.
For MVVMCross especially:
OnFragmentChanging(fragInfo, ft);
ft.Commit();
SupportFragmentManager.ExecutePendingTransactions();
OnFragmentChanged(fragInfo);
The OnFragmentChanged-Event should obviously only be called if the changes got applied. Just to take one of the code snippets out of MvxCachingFragmentCompatActivity.
From the API documentation.
After a FragmentTransaction is committed with
FragmentTransaction.commit(), it is scheduled to be executed
asynchronously on the process's main thread. If you want to
immediately executing any such pending operations, you can call this
function (only from the main thread) to do so. Note that all callbacks
and other related behavior will be done from within this call, so be
careful about where this is called from.

Related

What happens in Xamarin when Forms.Init gets called and the function is already running in another thread?

I'm thinking about how to reduce the cost of loading Forms.Init during the start of my app.
There's some work my app does that I can already do without access to Xamari.Forms. I'm thinking about loading Forms.Init in parallel in another thread.
In case that thread isn't yet finished and I already need Xamari.Forms, I'm not sure what my option are at handling the event.
What happens in Xamarin when Forms.Init gets called and the function is already running in another thread? Or are there otherwise best practices of dealing with loading Forms.Init in parallel to other work?
Forms.Init() calls the private SetupInit() which runs platform dependent code ranging from getting an Android Context, registering renderers, adding log listeners, etc...
Assembly callingAssembly = Assembly.GetCallingAssembly ();
SetupInit (activity, callingAssembly);
There are no callbacks or events tried to the competition of Init other then its synchronous completion, but there is a boolean flag that can be checked:
global::Xamarin.Forms.Forms.IsInitialized
But, depending upon platform, this flag can be set at the beginning of the method or at the end and also note there is no lock on setting this flag (which would cause a performance hit).
So, if the other code you need to run can be done completely without Forms, yes, you could do run this in parallel.
Your Application subclass and its LoadApplication step, of course, should not be done until Init() is finished.
re: https://github.com/xamarin/Xamarin.Forms

Cancel currently running function/goroutine

I'm using gin-gonic as HTTP handler. I want to prerender some graphical resources after my users make POST request. For this, I put a middleware that assign a function (with a timer inside) to a map[string]func() and call this function directly after assignation.
The problem is, when the user make two subsequent request, the function is called twice.
Is there any way to clear function ref and/or his currently running call like a clearInterval or clearTimeout in Javascript ?
Thanks
No; whatever function you've scheduled to run as a goroutine needs to either return or call runtime.Goexit.
If you're looking for a way to build cancellation into your worker, Go provides a primitive to handle that, which is already part of any HTTP request - contexts. Check out these articles from the Go blog:
Concurrency Patterns: Context
Pipelines and cancellation
I suppose your rendering function is calling into a library, so you don't have control over the code where the bulk of the time is spent. If you do have such control, just pass a channel into the goroutine, periodically check if the channel is closed, and just return from the goroutine if that happens.
But actually I would recommend a different, and simpler, solution: keep track (in a map) of the file names (or hashes) of the files that are currently being processed, and check that map before launching a second one.

NSUrlConnection synchronous request without accepting redirects

I am currently implementing code that uses macOS API for HTTP/HTTPs requests in a Delphi/Lazarus program.
The code runs in its own thread (i.e. not main/ui thread) and is part of a larger threading based crawler across Windows/Mac and Delphi/Lazarus. I try to implement the actual HTTP/S request part using the OS API - but handle e.g. processing and taking action upon HTTP headers myself.
This means I would like to keep using synchronous mode if possible.
I want the request to simply return to me what the server returns.
I do not want it to follow redirects.
I currently use sendSynchroniousRequest_returningResponse_error
I have tried searching Google, but it seems there is no way when using synchronous requests? That just seems a bit odd.
No, NSURLConnection's synchronous functionality is very limited, and was never expanded because it is so strongly discouraged. That said, it is technically possible to implement what you're trying to do.
My recollection, from having replaced that method with an NSURLSession equivalent once (to swizzle in a less leaky replacement for that method in a binary-only library), is that you need to basically write a method that uses a shared dictionary to store a semaphore for each NSURLSessionDataTask (using the data task as a key). Then, you set the semaphore's count to zero so that it will block immediately when you wait on it, asynchronously start an asynchronous request on the main thread, and then wait on the semaphore (in the current thread). In the asynchronous data task's completion handler block, you increment the semaphore, thus unblocking the calling thread.
The trick is to ensure that the session runs its callbacks on a thread OTHER than the current one (which is blocked waiting for the semaphore). So you'll need to dispatch_async into the main thread when you actually start the data task.
Ostensibly, if you supported converting the task into a download task or stream task in the relevant delegate method, you would also need to take appropriate action to update the shared dictionary as well, but I'm assuming you won't use that feature. :-)

Is it a good practice to call action within another action (in flux)

I have an action as follows:
SomeActions.doAction1(){
//..dispatch event "started"...
//...do some process....
FewActions.doAnotherAction(); //CAN WE DO THIS
//...do something more....
//..dispatch event "completed"..
}
While the above works with no problems, just wondering, if it is valid according to flux pattern/standard or is there a better way.
Also, I guess calling Actions from Stores are a bad idea. Correct me if I am wrong.
Yes, calling an Action within another Action is a bad practice. Actions should be atomic; all changes in the Stores should be in response to a single action. They should describe one thing that happened in the real world: the user clicked on a button, the server responded with data, the screen refreshed, etc.
Most people get confused by Actions when they are thinking about them as imperative instructions (first do A, then do B) instead of descriptions of what happened and the starting point for reactive processes.
This is why I recommend to people that they name their Action types in the past tense: BUTTON_CLICKED. This reminds the programmer of the fundamentally externally-driven, descriptive nature of Actions.
Actions are like a newspaper that gets delivered to all the stores, describing what happened.
Calling Actions from Stores is almost always the wrong thing to do. I can only think of one exception: when the Store responds to the first Action by starting up an asynchronous process. When the async process completes, you want to fire off a second Action. This is the case with a XHR call to the server. But the better way is to put the XHR handling code into a Utils module. The store can then respond to the first Action by calling a method in the Utils module, and then the Utils module has the code to call the second Action when the server response comes back.

Flux Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch

My code
https://gist.github.com/ButuzGOL/707d1605f63eef55e4af
So when I get sign-in success callback I want to make redirect,
redirect works through dispatcher too.
And I am getting Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch.
Is there any hack to call action in the middle ?
I don't see where in the gist that you posted you are doing the redirect. I only see the AUTH_SIGNIN and AUTH_SIGNIN_SUCCESS actions, and they look pretty straightforward.
But no, there is no hack to create an action in the middle of a dispatch, and this is by design. Actions are not supposed to be things that cause a change. They are supposed to be like a newspaper that informs the application of a change in the outside world, and then the application responds to that news. The stores cause changes in themselves. Actions just inform them.
If you have this error, then you need to back up and look at how you're handling the original action. Most often, you can set up your application to respond to the original action, accomplish everything you need to do, and avoid trying to create a second action.
You can make it work by "scheduling" the next action instead of calling it directly, here is an example code:
// instead of doing this
Dispatcher.dispatch(...);
// go like this
setTimeout(function() {
Dispatcher.dispatch(...);
}, 1);
This will cause your next dispatch to be called later out of the current dispatch process, and no error will happen.
If your dispatch code is on a callback any kind of other async operation that will work as well (for example in a response for an Ajax request).
I'm using this style to make some forms respond to generic data here and I'm facing no issue, at least the way I'm using it.
you can user the "defer" option in the dispatcher.
In your case it would be like:
Dispatcher.dispatch.defer(...);
You can check if the dispatcher is dispatching, such as:
if(!MyDispatcher.isDispatching()) {
MyDispatcher.dispatch({...});
}

Resources