KeepScreenOnRequest.RequestActive Not Working - c#

For my Windows Store App, I want my application to be active all the time.
I am using code below. My Device set to be go into screen lock in 10 seconds, while I am using my application it still goes into lock screen. Am I using this code incorrectly?
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
// Prevent tablet from sleeping while app is running
Windows.System.Display.DisplayRequest KeepScreenOnRequest = new Windows.System.Display.DisplayRequest();
KeepScreenOnRequest.RequestActive();
}

I think you should try it on page navigation events instead of application level events...
using Windows.System.Display;
private DisplayRequest KeepScreenOnRequest;
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
if(KeepScreenOnRequest == null)
KeepScreenOnRequest = new DisplayRequest();
KeepScreenOnRequest.RequestActive();
}
protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
{
base.OnNavigatingFrom(e);
KeepScreenOnRequest.RequestRelease();
}
Again in this scenario you have to handle the request and release part on all of your app's pages individually...

I think the problem may be elsewhere - your DisplayRequest may be garbage collected. Try like this:
Windows.System.Display.DisplayRequest KeepScreenOnRequest;
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
KeepScreenOnRequest = new Windows.System.Display.DisplayRequest();
// Prevent tablet from sleeping while app is running
KeepScreenOnRequest.RequestActive();
}
Few notes:
of course the above code should work for the whole app, when not needed - release the request
putting this in OnNavigatedFrom/OnNavigatedTo may not be a good idea, unless handeled properly - for example when app is suspended (common case) after you return OnNavigated won't be called - your DisplayRequest probably won't be activated
you don't need to worry about releasing you request while the app goes to background, as mentioned at MSDN:
Note Windows automatically deactivates your app's active display requests when it is moved off screen, and re-activates them when your app comes back to the foreground.

Related

Why Does a C# Web App ReBuild Result in Application_End() Call?

I noticed that while debugging my applications, sometimes the [InProc] Session State is destroyed following re-builds (C# Web Application). The sequence of events are as follows:
Rebuild & run application (Debug or Release Mode, Doesn't Matter)
Populate a Session Variable in Page_Load() Event
Session_End() fires then Application_End fires()
I perform a postback and check for Session variable populated in Step 2, it is empty.
I am running this application using IIS Express, but it seems to occur irregardless of which web server is being used. This is causing numerous problems as the application isn't counting on Session variables to vanish.
namespace BlankWebApp
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
Session["test"] = true;
}
}
protected void butCheckSession_Click(object sender, EventArgs e)
{
if (Session["test"] == null)
{
// Session_End and Application_End must have been called
}
}
}
}
Changing content of bin folder will cause application pool recycling. This is what is happening with the Re-Build, as rebuild will compile the application and create a new dll/executables for the project causing changes in the bin folder. Application pool recycling will cause the session to be removed from server memory.
Similar is true for changing Web.Config file as well.
You can't avoid that. You should have a separate development and production environment.

Xamarin Android Finalizer not getting called when leaving the activity to go to another Activity

The Finalizer is never called after leaving the activity. Does that mean the activity is still alive even though I moved on to the next activity.
namespace XamarinTest {
[Activity(Label = "XamarinTest", Icon = "#drawable/icon")]
public class MainActivity : Activity {
private int count = 1;
private TextView density;
protected override void OnCreate(Bundle bundle) {
base.OnCreate(bundle);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.ScreenData);
density = FindViewById<TextView>(Resource.Id.Density);
var pendingInent = new Intent();
pendingInent.SetFlags(ActivityFlags.ClearTop);
pendingInent.SetClass(this, typeof(TestActivity));
StartActivity(pendingInent);
Finish();
}
~MainActivity() {
Console.WriteLine("Finalizer called");
}
protected override void Dispose(bool disposing){
if (disposing) {
density.Dispose();
density = null;
}
base.Dispose(disposing);
}
}
}
This is actually remarkably complicated; the short answer, regarding the activity still being alive, is yes and no. Providing you have cleaned up the resources for your Activity correctly, your activity will be cleaned up (eventually) by the garbage collector.
Regarding cleanup, it's import to know that Xamarin discourages (slide 44 onwards) using finalizers. Here's why:
They are not guaranteed to run within any deadline.
They don't run in a specific sequence.
They make objects live longer.
The GC doesn't know about unmanaged resources.
Therefore, using a finalizer to perform cleanup is the wrong way of doing things... If you want to ensure that MainActivity is destroyed, manually dispose the Activity in it's OnDestroy callback:
protected override void OnDestroy ()
{
base.OnDestroy ();
this.Dispose (); // Sever java binding.
}
This will cause Mono to break the peer object connection and destroy the activity during the next garbage collection cycle (GC.Collect(GC.MaxGeneration)). From the docs:
To shorten object lifetime, Java.Lang.Object.Dispose() should be invoked. This will manually "sever" the connection on the object between the two VMs by freeing the global reference, thus allowing the objects to be collected faster.
Note the call order there, this.Dispose() must be called after any code that invokes back into Android land. Why? All the connections between Java and .NET are now broken to allow Android to reclaim resources so any code that uses Android-land objects (Fragment, Activity, Adapter) will fail.
Now, onto some debugging techniques for Activity leaks. To verify that your activity is being cleaned up, add the following code to the OnCreate method of your apps entry Activity:
var vmPolicy = new StrictMode.VmPolicy.Builder ();
StrictMode.SetVmPolicy (vmPolicy.DetectActivityLeaks().PenaltyLog().Build ());
This enables StrictMode, a useful debugging tool that happily informs you when you've leaked resources. When one of your apps activities isn't released correctly, it will dump something like this to the output stream:
[StrictMode] class activitydispose.LeakyActivity; instances=2; limit=1
[StrictMode] android.os.StrictMode$InstanceCountViolation: class activitydispose.LeakyActivity; instances=2; limit=1
[StrictMode] at android.os.StrictMode.setClassInstanceLimit(StrictMode.java:1)
Combining this with the Dispose() call, you can check that activities are being released. Here is how you'd typically an Activity and its resources in Xamarin.Android:
protected override void Dispose (bool disposing)
{
// TODO: Dispose logic here.
base.Dispose (disposing);
GC.Collect(GC.MaxGeneration); // Will force cleanup but not recommended.
}
protected override void OnDestroy ()
{
if (density != null) { // Release Java objects (buttons, adapters etc) here
density.Dispose ();
density = null;
}
base.OnDestroy ();
this.Dispose (); // Sever java binding.
}

detect shutdown in window service

i have a windows service that get user details and save the result into log text file. and, my problem is when i shut down or log off my system, i also would like to save the time that i down my system into that log file. but, i don't know how to do that.
I checked the winproc method to detect shutdown operation but i was not able to use it on window service, on googling found it can be used with forms only. how can we detect user have clicked shutdown or log off and do some action.
so,please give me some idea or suggestion on that.
i have used it for logoff but on log entry is made when i logoff the system
protected override void OnSessionChange(SessionChangeDescription changeDescription)
{
this.RequestAdditionalTime(250000); //gives a 25 second delay on Logoff
if (changeDescription.Reason == SessionChangeReason.SessionLogoff)
{
// Add your save code here
StreamWriter str = new StreamWriter("D:\\Log.txt", true);
str.WriteLine("Service stoped due to " + changeDescription.Reason.ToString() + "on" + DateTime.Now.ToString());
str.Close();
}
base.OnSessionChange(changeDescription);
}
For a shutdown, override the OnShutdown method:
protected override void OnShutdown()
{
//your code here
base.OnShutdown();
}
For a logoff:
First, add an event handler to Microsoft.Win32.SystemEvents.SessionEnded in the Service Constructor:
public MyService()
{
InitializeComponent;
Microsoft.Win32.SystemEvents.SessionEnded += new Microsoft.Win32.SessionEndedEventHandler(SystemEvents_SessionEnded);
}
Then add the handler:
void SystemEvents_SessionEnded(object sender, Microsoft.Win32.SessionEndedEventArgs e)
{
//your code here
}
This should catch any ended session, including the console itself (the one running the services).
Tl;dr
In your service set
CanShutdown = true;
then override
protected override void OnShutdown()
{
//Your code here
//Don't forget to call ServiceBase OnShutdown()
base.OnShutdown();
}
Now the extended answer
I know I'm bringing this up from the dead but I found it helpful and hope to add a little to the topic. I'm implementing a WCF duplex library hosted in a Windows Service and came across this thread because I needed to detect, from within the windows service, when a user logs off or shuts down the computer. I'm using .Net Framework 4.6.1 on Windows 7 and Windows 10. Like previously suggested for shutdown what worked for me was overriding ServiceBase.OnShutdown() like so:
protected override void OnShutdown()
{
//Your code here
//Don't forget to call ServiceBase OnShutdown()
base.OnShutdown();
}
Remember to add the following to your service's constructor to allow the shutdown event to be caught:
CanShutdown = true;
Then to capture when a user logs off, locks the screen, switches user, etc. you can just override the OnSessionChange method like so:
protected override void OnSessionChange(SessionChangeDescription changeDescription)
{
if (changeDescription.Reason == SessionChangeReason.SessionLogoff)
{
//Your code here...
//I called a static method in my WCF inbound interface class to do stuff...
}
//Don't forget to call ServiceBase OnSessionChange()
base.OnSessionChange(changeDescription);
}
And of course remember to add the following to your service's constructor to allow catching of session change events:
CanHandleSessionChangeEvent = true;
You should override OnShutdown in your service
// When system shuts down
protected override void OnShutdown()
{
// Add your save code here
base.OnShutdown();
}
You might also want to override OnStop
// When the user presses stops your service from the control panel
protected override void OnStop()
{
// Add your save code here too
base.OnStop();
}
Edit:
If you really want to listen to the shutdown event Microsoft.Win32.SystemEvents.SessionEnding is the way to go.
Maybe you can use this. Poll the method in question every now and then (1 second interval) and you'll be able to do what you want.
You need RegisterServiceCtrlHandlerEx API call.
Disclaimer
Maybe this answer wont be useful when Windows changes the Shut down behavior again.
Which notifications occur when computer Shutsdown?
As far as i was able to find out, three notifications occur when the computer shuts down:
SessionLogoff
SessionLock
Suspend
The first two are delivered by OnSessionChange(), and the last by OnPowerEvent().
Of course, a natural choice is Suspend, but care should be taken that this notification is also sent when the computer is sent to Sleep.
How to get notified?
To get the notifications posted above you have to allow the notifications in the service constructor as follows:
public Service1()
{
InitializeComponent();
CanHandlePowerEvent = true;
CanHandleSessionChangeEvent = true;
}
and then override the respective
protected override void OnSessionChange(SessionChangeDescription changeDescription)
{
// Do something
base.OnSessionChange(changeDescription);
}
protected override bool OnPowerEvent(PowerBroadcastStatus powerStatus)
{
// Do something
return base.OnPowerEvent(powerStatus);
}
What about ServiceBase.OnShutdown()?
Well, this is not called when a computer is shut down by clicking on "Shut down" in the Power options.
Indeed, as written in this official post,
When you shut down your computer, your computer actually enters a hibernation state instead of a full shutdown.
and further, according to the documentation:
Use OnShutdown to specify the processing that occurs when the system shuts down.
This event occurs only when the operating system is shut down, not when the computer is turned off.
OnShutdown is expected to be overridden when the CanShutdown property is true.
So, if manually shutting down the computer does not really shuts down the computer, but it puts it in an hibernation state, what can shut down the computer?
The post quoted above has again the answer:
Full shutdown only occurs when you restart a computer or when other event causes the computer to process a full shutdown.
And indeed, i could get the OnShutdown() method called on my service by setting
CanShutdown = true;
and overriding to OnShutdown
protected override void OnShutdown()
{
// Do something
base.OnShutdown();
}
and then restarting my computer.
Well, enough with this post. I only hope the shut down behavior of Windows does not change soon...

dispatcher timer for sending periodic data

I want to send some kind of hearbeat at every configured time interval. I want to use dispatcher timer to send it.
Main()
{
create dispatcher timer;
}
void dispacthertimertick()
{
// send heartbeat
}
How do i keep the main thread alive?
Regards
Raju
The best place to put it is in your App.xaml.cs.
Application in WPF is responsible for setting the message loop so you should not really worry about it. If your App.xaml has a build action property of ApplicationDefinition (which is the default), it will emit this start up code (which you can see using Reflector):
[STAThread, DebuggerNonUserCode]
public static void Main()
{
App app = new App();
app.InitializeComponent();
app.Run();
}
You need to use OnStartup:
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
// setup your timer here
}
Console.Read() is really a hack and unnecessary since there could be no console, as is the case in Windows forms.

Android with Xamarin - How to run code when the user closes the App? [duplicate]

This question already has answers here:
Can you track when an android application has been terminated?
(3 answers)
Closed 6 years ago.
I found some questions/answers on how to track when the app goes to the background, like this one:
Run code when Android app is closed/sent to background
But I need to run the code only if the user actually closes the application.
To exemplify:
The user clicks on the Overview button;
The Android opens the list of thumbnail images of the recent apps;
The user swipe the thumbnail of my app to remove it (here is where I need to run the code).
I tried to add some code to the OnDestroy() method, but it don't seem to be called when I do steps above. I know the code works because I've done a test where I call the Finish() right at the start of my OnCreate(), then the OnDestroy() is called and so my code.
I'm using Xamarin and MvvmCross, but Java code is welcome too.
Implement and register an instance of Android.Content.IComponentCallbacks2 and the listen for TrimMemory.UiHidden events:
LifecycleCallbacks:
public class LifecycleCallbacks : Java.Lang.Object, Android.Content.IComponentCallbacks2
{
public void OnTrimMemory(TrimMemory level)
{
if (level == TrimMemory.UiHidden)
{
Console.WriteLine("Backgrounded...");
}
}
public void OnConfigurationChanged(Configuration newConfig)
{
}
public void OnLowMemory()
{
}
}
Registering an instance of LifecycleCallbacks:
[Activity (Label = "MyApp", MainLauncher = true)]
public class MainActivity : Activity
{
protected override void OnCreate (Bundle savedInstanceState)
{
base.OnCreate (savedInstanceState);
// ...
Application.RegisterComponentCallbacks(new LifecycleCallbacks());
// ...
}
}
Native android developer here, I'm not sure if Xamarin extends the native framework somehow making this possible, but natively it's currently not supported.
The OS does not necessarily call activities' onDestroy method when the app is killed, but when the Activity is killed. It's really different because the App can be killed without calling activities' onDestroy and the onDestroy can be called without the Application being killed.
I recommend looking up to Services and the Alarm Manager to actually track when this occurs, allied to the onDestroy and onPause methods. The precision in that case will be as good as you want. You can call an alarm every minute to check it for example, or run a background service in its own process that will remain active after the application is killed.
There's a comprehensive discussion about this in another question. It's about native code, but the explanation of the problem is very useful for you to understand the limits of the framework.

Categories

Resources