I am using a background thread to make an async call to the web service and return the results.When the background thread is running and my app gets deactivated, say the user presses the home button, How do I handle it?
private async void Application_Deactivated(object sender, DeactivatedEventArgs e)
{
//What should I do here?
}
I understand from the following blog http://www.wintellect.com/blogs/jgarland/proceed-with-caution---windows-phone-8-app-lifecycle-events-vs-async-methods that I cannot await till the background threads complete in the deactivated method.Also it suggests using synchronous calls.In case I have to cancel my background thread inside deactivated event,How do I find which background thread is running at the moment?In every page where web service is called , a background thread is used.Is there any way to resume a background thread after app is activated again?
You are right that when your App is deactivated then all processes are stopped - MSDN source:
When the user navigates forward, away from an app, after the Deactivated event is raised, the operating system will attempt to put the app into a dormant state. In this state, all of the application’s threads are stopped and no processing takes place, but the application remains intact in memory.
In your deactivated event you should invoke Cancel request to all your background threads. If you are using aync-await then you can equip those methods with CancellationTokenSource. Here is some more about this: Enabling Progress and Cancellation in Async, Cancel an Async Task or a List of Tasks , and you can find lot of information on Stephen Cleary blog.
As for the question to know which Task is running I think you can use this CancellationTokenSource to check it - if it isn't null then it means that your bacground thread is working.
And as for reacivating your method - everything depends on your code and what that method perform. If you are downloading a group of files then you can remember which are downloaded and after activation call method downloading the rest. If you perform some calculation then you can remember the place where the method stopped and try to resume further calculations. Thought it can be sometimes hard. And you must remember that you have limited time to 10 seconds:
You should not wait until the Deactivated event occurs to store this data. Remember that all application lifecycle events enforce a limit of 10 seconds for an application to complete any tasks.
About other possibilities:
If you want to perform some actions in background proces - then you can use Background agents and Background transfers if you want to download a file. There is also Background audio, but I suppose you are not asking about it.
If you want your app to stay in foreground when lock screen is engaged then you can Deactivate Idle Detection.
Related
I have been testing a C# Companion Device Framework application, which unlocks my laptop fine for the most part. However, it doesn't seem to work after I leave my laptop locked for a while.
I used the code from the CDF GitHub sample to fire a toast notification when the background task for my UWP companion app is triggered.
This shows me that there is never an issue when I attempt an unlock shortly after locking the machine. When I lock my machine, I immediately see the toast notification indicating that the background task was triggered. However, if I lock my laptop and leave it for a few minutes, it doesn't appear that the background task gets triggered again, even though I wake up the screen and press buttons.
I want my CDF app to always be able to unlock my machine. What did I do wrong? Hopefully I don't need it, but is there a workaround like registering a second trigger for the background task to a custom service?
UPDATE: It appears this occurs only if the computer does not go to sleep, which may occur in the case that someone has either set a long time before sleep or has sleep off completely (as I did previously). If the laptop does go to sleep, and has to be woken up with a trackpad click, then the background task seems to fire.
The problem is, Windows UWP stops to fire the event WaitForUserConfirmation after awhile.
At present, we have 2 possible solutions:
user hits the keyboard and the background task catches the event CollectingCredential and invokes the companion device authentication
once the background task is running, it loops until the event CredentialAuthenticated, and it runs the companion device authentication periodically.
I created app for universal windows platform(for Windows 10 desktop). I use DispatcherTimer in app. Timer run async method. When app in foreground it is work.
But app is background(I minimize a window) async method not work. How can I solve this problem?
When your app is not running in the foreground and tasks need to be executed, it is well known that we need to implement the background tasks for the app.
But, background tasks in UWP are lightweight. Due to memory constraints, battery life issue, I'm not sure what you need can be done in background task of UWP.
That doesn't mean you can't use DispatcherTimer in the background task, but background tasks are limited to 30 seconds of wall-clock usage, and it can be terminated by system for example when it throw the out-of-memory exception. So, if you want to execute your task every one minute, then it will not work.
The TimerTrigger which is mentioned by #ibebbs has a minimal time intervals which is 15 minutes, so I'm also not sure this can be used in your scenario.
Problem is what you need to do in the background task and how often, you can leave a comment to tell that, so can we continue to discuss on this issue.
You should Create and register a background task that runs in a separate process and use a TimerTrigger to invoke it at the desired interval.
I've posted previously about synchronisation issues with my background scheduled task having to access a SQLite DB and IsolatedStorge that the foreground app uses.
To simplify the process I thought about just preventing my background task from running altogther, it isn't imperative that it runs, especially when the foreground app is active.
Is there a way to do this?
I thought about using IsolatedStorage to set a flag when the app launches then remove it when it exits, then have the background task check the setting, protected by mutex.
I think the idea is fine in principle, but I guess there will be times when the flag isn't unset, for example if the battery dies... Which means potentially, after turning the phone on, if the user never uses the app and exits properly, the background task will never run. This might not be too much of an issue.
Is using some kind of flag like this the only way to achieve such functionality?
Thanks
There is an inter process communication mechanism to achieve this functionality.
As both the foreground app and scheduletask run as different processes, IPC could be used for it.
Please refer to Named Events.
In your OnInvoke Method subscribe for a named event which will be fired by your foreground app as soon as it is launched/resumed.
As soon as you get a signal via this event in background agent, just call NotifyComplete and you are done.
I have a large WPF app with few threads ( all threads use dispatcher.invoke to update the GUI) and many grids and controls. At any give time only 2 or three grids are visible so the user can interact with the controls. I also have an external device which sends a signal to my app and I then update the GUI so the user knows the signal was fired.
I do the update through a dispatcher since the signal detection is on another thread. So everything is fine until intermittently it takes 5 minutes for the dispatcher.invoke with normal priority to call my method. when this happens as soon as I click the GUI then method gets called immediately. So it seems that message pump is asleep or hung and as soon as I click on the GUI it wakes up and process my message. I have done this several times so I am sure that message queue wakes up upon refreshing the GUI.
So is this a bug in WPF message pump queue where it occasionally goes to sleep and wakes up when the GUI is refreshed? or what is the reason for this behavior and what to do about it.
Thanks in advance
apologies if I don't explain this clearly, but I'm writing an app which is causing me some problems with threading.
I have a UI which starts a System.Timers.Timer. Each time this timer elapses it triggers a workflow which opens a progress screen. To prevent another workflow starting before the last one has finished it locks an object on the main form.
This progress screen starts and reports the progress of, some file copying using FileCopyEX.
The problem I'm having is that the progress screen does not display until after the work flow has been completed.
Hopefully this will make it clearer:
Main Form
|
Timer Elapses
|
WorkFlow Starts
|
Progress Screen opens (errors which occur go back to the previous)
|
File copying occurs (progress reported back to progress screen)
If no errors, returns to main screen before next tick.
Until now I've only implemented very simple threading, so I'm not sure how best to implement this. I've tried starting the workflow on a BackGroundWorker to seperate it from the UI thread but it behaves the same.
Thanks
I suggest that you read about the BackgroundWorker. This has hooks for reporting progress.
Remember that system timers invoke its event handler on a non-UI thread. Whenever, you do something with the UI you must be on the UI thread.
Without the code I can only guess at the cause, but the likely reason is that the Progress window needs the UI to be pumping messages to appear - i.e. the UI thread needs to be running.
If the UI thread is busy running your workflow, then it won't get around to processing the displaying of your window until after that. You need to separate your flow so that the progress window is on your UI thread and the workflow is on a background thread.
Hope that makes sense!