I am working with Xamarin.iOS and implementing a Downloadmanager.
I have found a tutorial on how to implement a DownloadManager in swift, lead by that tutorial I have transcribed the logic written in swift into C#. The DownloadManager works and queues Operations and executes them. The only issue I am facing is the transition of the App to suspended mode. The behavior of the queue is not so deterministic. Sometimes all queued operations are executed and sometimes the app stops the execution.
Use Case 1:
I start the file sync and lock the iPad. Most of the time the queued operations are executed. But sometimes when I unlock the iPad the Application is send to the background and I have to double tap the home button to return to the Application, in this case the file sync has stopped somehow in the middle of execution.
Use Case 2: I start the file sync and send the app to the background. The same behavior like in the previous use case. Sometimes all operations are executed and sometimes the operations stops.
Use Case 3: The customer starts the sync and leaves the iPad unattended after some time he comes back and the Sync is not finished and the Application is in the background. In average about 70% of the sync is done.
For the implementation I have used a "NSOperationQueue" that has "DownloadOperation" as elements. The "DownloadOperation" are just a wrapped of the NSOperation object with the execution set to "Asynchronous".
Possible Questions
I am not sure what happens to the "NSOperationQueue" when the Application changes states?
Is the usage of the "NSOperationQueue" the "right" way to go with the implementation of a DownloadManager?
Are there any common tips for the optimisation of the execution of the "NSOperationQueue" and/or the "NSOperation"
Looking forward to the discussion.
P.S. I have enabled "Background Modes" and "Background Fetch"
According to your description, I suppose you used the NSURLConnection to execute background download which is deprecated. Also, Background Fetch is for small amounts of content and it will be active opportunistically, which is not appropriate for your scenario:
Fetching Small Amounts of Content Opportunistically
Apps that need to check for new content periodically can ask the system to wake them up so that they can initiate a fetch operation for that content.
So, you could switch to use NSURLSession which is officially recommended for downloading content in background. To configure a background session, the download process will be still ongoing in case the app is suspended or terminated(except user has forced quite the app). Refer to this Apple documentation:
Downloading Content in the Background
When downloading files, apps should use an NSURLSession object to start the downloads so that the system can take control of the download process in case the app is suspended or terminated. When you configure an NSURLSession object for background transfers, the system manages those transfers in a separate process and reports status back to your app in the usual way. If your app is terminated while transfers are ongoing, the system continues the transfers in the background and launches your app (as appropriate) when the transfers finish or when one or more tasks need your app’s attention.
...
If tasks have not yet finished and the system terminates your app, the system automatically continues managing the tasks in the background. If the user terminates your app, the system cancels any pending tasks.
About how to create a download manager for background via NSURLSession, you can refer to:
Blog with swift: Downloading files in background with URLSessionDownloadTask
Xamarin guides: Walkthrough - Using Background Transfer Service and NSURLSession
I think you need to download multiple files in background, here's a good guide for you: Downloading multiple files in batches in iOS
.
Related
I'm developing a Revit add-on which performs some lengthy tasks. During the process, I want to display a simple WPF window with an indeterminate progress bar, a label to inform about current process and a button to enable aborting.
I already tried the most obvious ways of accomplishing that: creating a WPF window inside the add-on and displaying it, but the problem is that the UI gets frozen, no matter how I implement this. During some processes, the whole Revit UI gets frozen/white so I really wouldn't expect my embedded WPF window would behave normally in these conditions anyway.
The workaround I figured out was to have the WPF window as a separate app (EXE file) I could run from the add-on. I based my implementation on this example .
The good part of it is that it doesn't hang no matter what is happening with Revit.
The bad part is that the sequence of how Windows is queuing the calls of my separate WPF app is sometimes different from the sequence of these calls from my add-on. It sometimes results in a situation when the Revit process is over but the WPF window is still displayed (waiting for the final, closing call which had been apparently already executed, but then the app got reactivated with another, delayed call).
Preferably I would like to handle the WPF app the same way as you can i.e. handle an Excel application from .NET. You create an ExcelApp object, do what you want with it and dispose of in the end.
The problem is I don't have a clue of how to do this.
How should I expose the WPF app's API to my add-on?
Could it be possible to have the WPF app responsive and controlled from the Revit add-on at the same time? (user can still click the abort button, the indeterminate progress bar doesn't freeze)
The First thing to know is about interacting between two processes. there are some Standard approaches:
Interacting through Socket (Socket Programming)
Using Named PipeLines (Useful when your messages aren't so long)
There are some other predefined Libraries based on above techniques. Using a FileSystem Based method is not a reliable way to proof the outputs.
This was a part of your solution. The next step is to use Threading in your WPF application. I'm not familiar to Revit and I don't know how it works.
UI freezing is normal in a long running process. because UI is busy and it can't answer your requests (e.g Mouse Move, Click, ...). So using a Thread you can put your long running process into a separate place and wait for the response at the end of it.
There is a problem while using a Thread. Because you left your UI and started your long running process on a separate Thread, you can't directly access to your ProgressBar. In this situations you have to use ThreadDispacher. It's not a terrifying concept, it just a three line of codes that will adds to your callings.
for example:
Dispatcher.Invoke(() =>
{
ProgressBar.Value++;
});
Search for a Library to doing your IPC (Inter Process Communication) to get the result faster (or you can learn about above techniques to do it by your means) and next add a simple thread to your WPF application so you be able to Start, Pause and resume the running job based on the situation.
I have a windows application that reads from a database and populates multiple Listview containers depending on what items the user selects. Some of the data in a particular Listview is right-clickable with a MenuItem option to ‘Write Data to Excel’. This may take around 10 minutes to complete.
I have the Excel Interop portion written in stand-alone code or can I incorporate it into the application project. The Excel Interop app takes only 1 parameter to do its thing.
My question is… should I incorporate it into the Windows App and use multithreading or run it as a standalone app (which seems more efficient), which is called from the Windows App? And what is a good way of doing that where the Windows app starts the process and then can forget about it.
I think that the answer for this one is answered by the question : "What should happen if the user closes the main application during those 10 minutes ?"
If the file should still be wrote, then a standalone application is perfect, cause your threads won't survive.
If the file creation should be interrupted, then I see no reason not to use multithreading, as it seems simpler by default, in particular debugging this part of the code is way easier if it's in the same application.
I would recommend for the below flow:
We can create our own queue which will be either maintained in database or file system.
Then we can write a scheduler which will fetch all the unprocessed request and with the respect to response mark appropriate status of queued item.
Now You application can just call the queuing process and move forward from there.
Use another thread to write it.
I doubt this is even possible. So your app is running and user decides to End Process via Task Manager. Is there a method/action to save data during process.kill? I doubt there is but I had to ask.
Also, if a user shuts down/restarts PC (as in windows update/manual restart), what action would the app execute? Window_Unloaded? On this second question, I would like to find a way to ensure my app does not show up as a 'if you want to restart, kill this app' situation and want to save needed data.
Your two cents is greatly appreciated!
It's not possible to do what you want unless you have two processes; one monitoring the other one's status and do some stuff upon its termination. The watchdog process might be a Windows Service Application without GUI.
Windows sends a quit message to every opened application when normal shutdown occurs. You can run some code (usually housekeeping stuff) upon receiving the message and exit the application. It shouldn't take long or Windows will automatically ask user if they want to kill the application.
Force shutdown kills all processes immediately (in no particular/predictable order). So you can't (easily) detect it.
I suggest you to save everything needed as soon as possible to prevent data loss when the application process gets killed.
If something terminates your running app, then you don't get an opportunity to do anything, just die. You modify your app such that all data is always saved to some persistent location, so if the app dies, the persisted data remains. Obviously you have to design for this. Then if the user does a "save", you commit to the "real" datastore.
If Windows is going to reboot, it should send a message to your app, which you can handle. Not sure if this works for all GUI/console/service -type apps however.
I've created a shiny new ASP.Net MVC site and I have offloaded the 'save as' type of functionality to a helper program that can be run in the background on the server so that the website doesn't need to take all that load.
I created it so that it's easy to run from the command line and right now I have it running from a windows scheduler. The problem is that that has a granularity of 1 minute, which means that some unlucky users of the website will click on the link and get a 59s wait + the time to actually process the report.
I'm also slightly worried about the start up cost of my program. I'm assuming that it would be cheaper to keep the program running constantly. I am worried about the program dying and not being respawned though. With the windows scheduler option at least I don't have to worry about my program bailing so much.
How have you dealt with that?
I'd create a Windows Service and have that running instead of an exe via windows scheduler. You can then set it to auto-start. Then you can just have a timer within the service to poll for work every x seconds.
Another alternative is to use something like MSMQ. Your front end would just insert a message into the queue to represent the work to do, then have a .NET service listening to the queue (you can get it to process messages immediately they appear in the queue, or check the queue manually yourself every x seconds).
Either way, I think a Windows Service is the way to go.
I've got about 40 lines of .NET code in a console application that read and RSS feed and store information in a database. I need this code to execute every night for as long as the RSS feed exists (indefinitely). Currently, I just launch the console app. from my home computer.
Because I can't trust myself to remember to do this every night, I somehow need to have this code hosted. I'd like to somehow have this app. or code (it could easily be put in an ASP.NET page codebehind and triggered to execute when the page loads) run automatically without me having to run the console app. manually.
Any ideas?
EDIT: I don't want to run this code from my computer; I can't guarantee my computer will not be hibernating or connected to the Internet every night.
EDIT: Right now I'm thinking spawn a background thread using BackgroundWorker in Application_Start of the global.asax, have it download the RSS feed once a day, and Thread.Sleep() the rest of the time.
Although controversial, Jeff Atwood blogged about how they accomplished this for SO using cache expiration. Check it out at https://blog.stackoverflow.com/2008/07/easy-background-tasks-in-aspnet/.
You could use a similar method and schedule the cache to expire at the time you want the process to kick off.
You could use the Windows built-in task scheduler to start the console application.
I would suggest just using the 'at' command instead of getting this small app hosted somewhere.
C:\>at /?
The AT command schedules commands and programs to run on a computer at
a specified time and date. The Schedule service must be running to use
the AT command.
Email your webhost. Some managed hosts will set up a scheduled task for you.
They will likely have different policies regarding how to call a scheduled task (i.e. some may require it to be an aspx page and not an EXE)
Have you looked at Quartz Scheduler for .NET?
Quoth the tagline: Quartz.NET is a full-featured, open source job scheduling system that can be used from smallest apps to large scale enterprise systems.