I have an UWP app with a lot of errors in dev center console during launch such as this:
em_watchdog_timeout_deada444_514cabuxamapache.391043fc20bb3_fa4730peekfge!lockscreenimages.exe_timeout_expired:_event_type_=_targetstatechanged,_timeout_modifier_type_=_none,_server_task_currentstate_=_navigatingto,targetstate=_active.
I suspect it's due to Cortana or Analitycs activation in "App.cs":
private async Task SetupVoiceCommands()
{
try
{
StorageFile vcdStorageFile = await Package.Current.InstalledLocation.GetFileAsync(#"Commands.xml");
await VoiceCommandDefinitionManager.InstallCommandDefinitionsFromStorageFileAsync(vcdStorageFile);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("Installing Voice Commands Failed: " + ex.ToString());
}
}
private void InitAnalyticsTracker()
{
GoogleAnalyticsTracker = AnalyticsManager.Current.CreateTracker("UA-XXXXXXXX");
AnalyticsManager.Current.ReportUncaughtExceptions = true;
AnalyticsManager.Current.AutoAppLifetimeMonitoring = true;
AnalyticsManager.Current.IsDebug = false;
}
This code is executed in:
protected override async void OnLaunched(LaunchActivatedEventArgs e)
{
Frame rootFrame = Window.Current.Content as Frame;
if (rootFrame == null)
{
rootFrame = new Frame();
rootFrame.NavigationFailed += OnNavigationFailed;
if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
//TODO: Load state from previously suspended application
}
Window.Current.Content = rootFrame;
}
if (e.PrelaunchActivated == false)
{
await SetupVoiceCommands();
if (rootFrame.Content == null)
{
InitAnalyticsTracker();
rootFrame.Navigate(typeof(Shell), e.Arguments);
}
else
{
var page = rootFrame.Content as Shell;
page?.OnLaunchedEvent(e.Arguments);
}
Window.Current.Activate();
CustomizeStatusBar();
}
}
A lot of users say the app does not even start...
Any ideas please?
The call await SetupVoiceCommands(); blocks the rest of the code in the OnLaunched method: until the execution of SetupVoiceCommands() is finished the main page of the app won't be displayed (which is supposed to happen within a short period of time after the app launch, otherwise the system will shut down your app as not responding).
Consider moving the await SetupVoiceCommands(); closer to the end of the OnLaunched method, e.g. after CustomizeStatusBar();.
To get a better understanding of how it affects the flow of execution and the launch time of the app, you could replace the call await SetupVoiceCommands(); with await Task.Delay(5000); to imitate the delay and then try moving it around the OnLaunched method as suggested.
Related
I trying to understand an example app by Microsoft. Now I can't repeat the next part. The app have classes App and ExtendedSplach. I want to repeat loading by ExtendedSplash. In my case, it's simple switch from splash to main page after some delay.
Introduction
The example to do like this.
If app runs with breakpoints on line .Content = extendedSplash and .Content = rootFrame, then the first will be extendedSplash. But line .Content = extendedSplash the follow after .Content = rootFrame. The constructor ExtendedSplash calls LoadDataAsync that set .Content = rootFram by first.
However, method LoadDataAsync contains await call
await Startup.ConfigureAsync();
I think that thus the first will extendedSplash. And we will see loading page.
class App
...
bool loadState = (e.PreviousExecutionState == ApplicationExecutionState.Terminated);
ExtendedSplash extendedSplash = new ExtendedSplash(e, loadState);
Window.Current.Content = extendedSplash;
Window.Current.Activate();
class ExtendedSplash
public ExtendedSplash(IActivatedEventArgs e, bool loadState)
{
...
LoadDataAsync(this.activatedEventArgs);
}
private async void LoadDataAsync(IActivatedEventArgs e)
{
...
rootFrame.Navigate(typeof(LoginView), shellArgs);
Window.Current.Content = rootFrame;
Window.Current.Activate();
}
Problem
I tried to repeat the same. I want see loading and then swith to other page. But my case with breakpoints looks like the first .Content = rootFrame and the second .Content = extendedSplash. Thus my queue are logo app with delay 5 seconds and then page with extendedSplash. The page rootFrame losing.
I will grateful for any help.
My code
I did the same by App class
bool loadState = (e.PreviousExecutionState == ApplicationExecutionState.Terminated);
ExtendedSplash extendedSplash = new ExtendedSplash(e, loadState);
Window.Current.Content = extendedSplash;
Window.Current.Activate();
And the next by ExtendedSplash
public ExtendedSplash(IActivatedEventArgs e, bool loadState)
{
this.InitializeComponent();
Window.Current.SizeChanged += new WindowSizeChangedEventHandler(ExtendedSplash_OnResize);
this.splashScreen = e.SplashScreen;
this.activatedEventArgs = e;
OnResize();
rootFrame = new Frame();
LoadDataAsync(activatedEventArgs);
}
private async void LoadDataAsync(IActivatedEventArgs e)
{
await Test();
rootFrame.Navigate(typeof(MainPage));
Window.Current.Content = rootFrame;
Window.Current.Activate();
}
private async Task Test()
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
while (stopwatch.ElapsedMilliseconds < 5000) ;
}
The problem with your code is in fact in the Test() method. You have marked is async, but that doesn't make the method asynchronous. Instead, your code will actually be stuck for five seconds in blocking manner in the while loop.
Try the following version:
private async Task Test()
{
await Task.Delay(5000);
}
This form of code is in fact asynchronous, so as a result the UI thread will be free to display the splash screen in the meantime.
In general - async methods run on the thread that calls them until they hit an "actual" asynchronous code - for example I/O bound async method or when you run your code with await Task.Run(()=>{...}.
I have created resource files (.resw) for French and English. Now I want to call resource file for "fr" on loading the first page of my app. I have done like below. But it shows an exception
"System.NullReferenceException: Object reference not set to an
instance of an object".
XAML
<TextBlock x:Uid="txt_launch3" Grid.Row="4" Padding="7"/>
Code-behind
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
string getDeviceDefaultLang="fr";
ChangeLanguage2(getDeviceDefaultLang);
}
private void ChangeLanguage2(string language)
{
try
{
ApplicationLanguages.PrimaryLanguageOverride =language;
Frame.CacheSize = 0;
Windows.ApplicationModel.Resources.Core.ResourceContext.GetForCurrentView().Reset(); Windows.ApplicationModel.Resources.Core.ResourceContext.GetForViewIndependentUse().Reset();
Frame.Navigate(this.GetType());
}
catch (Exception ex)
{
string exx = ex.ToString(); //getting System.NullReferenceException
}
}
}
The problem is that you are calling the method too early within the page. In the constructor the page is not yet assigned to the Frame it resides in. Because of this the Frame is still null there.
You could move the method call to the OnNavigatedTo override:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
string getDeviceDefaultLang = "fr";
ChangeLanguage2(getDeviceDefaultLang);
}
private void ChangeLanguage2(string language)
{
try
{
ApplicationLanguages.PrimaryLanguageOverride = language;
Frame.CacheSize = 0;
Windows.ApplicationModel.Resources.Core.ResourceContext.GetForCurrentView().Reset();
Windows.ApplicationModel.Resources.Core.ResourceContext.GetForViewIndependentUse().Reset();
Frame.Navigate(this.GetType());
}
catch (Exception ex)
{
string exx = ex.ToString(); //getting System.NullReferenceException
}
}
Alernatively you could directly access the root frame of the app instead of through the Frame property of the page:
private void ChangeLanguage2(string language)
{
try
{
ApplicationLanguages.PrimaryLanguageOverride = language;
var rootFrame = Window.Current.Content as Frame;
rootFrame.CacheSize = 0;
Windows.ApplicationModel.Resources.Core.ResourceContext.GetForCurrentView().Reset();
Windows.ApplicationModel.Resources.Core.ResourceContext.GetForViewIndependentUse().Reset();
rootFrame.Navigate(this.GetType());
}
catch (Exception ex)
{
string exx = ex.ToString(); //getting System.NullReferenceException
}
}
However, this is really not optimal, because you are essentially navigating while there is an navigation currently taking place (the original MainPage navigation.
Most likely you will call the change language in response to user action anyway (like button click), when none of this will be a problem anymore and Frame will be defined.
Update
The best solution would be to set the language override in the OnLaunched handler in App.xaml.cs:
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
Frame rootFrame = Window.Current.Content as Frame;
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == null)
{
// Create a Frame to act as the navigation context and navigate to the first page
rootFrame = new Frame();
rootFrame.NavigationFailed += OnNavigationFailed;
if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
//TODO: Load state from previously suspended application
}
// Place the frame in the current Window
Window.Current.Content = rootFrame;
}
if (e.PrelaunchActivated == false)
{
if (rootFrame.Content == null)
{
ApplicationLanguages.PrimaryLanguageOverride = "fr";
Windows.ApplicationModel.Resources.Core.ResourceContext.GetForCurrentView().Reset();
Windows.ApplicationModel.Resources.Core.ResourceContext.GetForViewIndependentUse().Reset();
// When the navigation stack isn't restored navigate to the first page,
// configuring the new page by passing required information as a navigation
// parameter
rootFrame.Navigate(typeof(MainPage), e.Arguments);
}
// Ensure the current window is active
Window.Current.Activate();
}
}
I am creating a uwp app with some media and video features, I have tested the app repeatedly on debug mode and it works just perfect as desired, after commenting and uncommenting of some code I was able to figure out that recursion of a specific method is causing the app to crash.
I also tried to display the exception with message dialog ( for release mode ). But no exception caught and app just freezes and crashed.
I run the app once on debug mode and then stop visual studio and then just directly open the app from my PC to test it on release mode.
MyScenario:
I am using OnFileActivated event to open video files directly on double click in my PC with my app. That works just fine. Below I will show you the code and reason for crashing. Please let me know how to solve this.
Thanks in advance.
Code
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
//Some Media Stuff which works fine everytime even in release mode.
await speechRecognizer.CompileConstraintsAsync();// I am using speech input to play pause my media player.
ListenandAct();
}
private async void ListenandAct()
{
var result = await speechRecognizer.RecognizeAsync();
if (result.Text == "Pause" || result.Text == "pause")
{
Media.Pause();
}
else if (result.Text == "Play" || result.Text == "play")
{
Media.Play();
}
//ListenandAct(); //if I comment this line for recursion the app doesnt crash even in release mode, but If I uncomment it than app works perfect in debug mode but crashes in release mode.
}
OnFileActivated method in app.xaml.cs
protected async override void OnFileActivated(FileActivatedEventArgs args)
{
string ParentName = "";
if (args.Files.Count > 0)
{
Type TargetType = typeof(MainPage);
if (args.Files.Count == 1)
{
SingleFileToPlay = args.Files[0] as StorageFile;
TargetType = typeof(SingleFilePlay);
}
else if (args.Files.Count > 1)
{
ParentName = (await (args.Files[0] as StorageFile).GetParentAsync()).DisplayName;
MultiFilesToPlay = new List<StorageFile>();
TargetType = typeof(MultiFilePlay);
foreach (var file in args.Files)
{
MultiFilesToPlay.Add(file as StorageFile);
}
}
Frame rootFrame = Window.Current.Content as Frame;
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == null)
{
// Create a Frame to act as the navigation context and navigate to the first page
rootFrame = new Frame();
rootFrame.NavigationFailed += OnNavigationFailed;
// Place the frame in the current Window
Window.Current.Content = rootFrame;
}
//if (rootFrame.Content == null)
//{
// When the navigation stack isn't restored navigate to the first page,
// configuring the new page by passing required information as a navigation
// parameter
rootFrame.Navigate(TargetType, ParentName);
//}
// Ensure the current window is active
Window.Current.Activate();
}
}
NOTE
When I run a video file by double clicking it , it works perfect without crashing, but when my app is already running a video file and I double click another video file again then my app tries to run the second video file, the second video file is shown on the app as it is suposed to and then app freezes and crashes after a couple of seconds.
I'm writing a UWP app, and I have a ScheduledToastNotification that is added to the schedule when the app is suspended (e.g. like a reminder). However, if I close the app, the notification appears on time, but when I click on the notification (no buttons, just on the notification in general), the app doesn't launch correctly, stopping at the splash screen.
How do I get the app the re-launch correctly?
Thanks.
You should override OnActivated in App.Xaml.cs and handle this like
protected override void OnActivated(IActivatedEventArgs args)
{
if (args.Kind == ActivationKind.ToastNotification)
{
var toastArgs = args as ToastNotificationActivatedEventArgs;
var arguments = toastArgs.Argument;
if (arguments == "ARG")
{
Frame rootFrame = Window.Current.Content as Frame;
if (rootFrame == null)
{
rootFrame = new Frame();
Window.Current.Content = rootFrame;
}
rootFrame.Navigate(typeof(YOURPAGE));
Window.Current.Activate();
}
}
}
I am having issues resuming my app after utilizing the PickFolderAndContinue method. I've been trying to go off the directions from this MSDN sample. I haven't been able to figure out how to change the OnActivated method to return to my Settings page (the sample uses only the mainpage with different frames of content).
protected async override void OnActivated(IActivatedEventArgs e)
{
base.OnActivated(e);
ContinuationManager continuationManager = new ContinuationManager();
Frame rootFrame = CreateRootFrame();
await RestoreStatusAsync(e.PreviousExecutionState);
if (rootFrame.Content == null)
{
rootFrame.Navigate(typeof(SettingsPage));
}
var continuationEventArgs = e as IContinuationActivatedEventArgs;
if (continuationEventArgs != null)
{
// What do i do here to return to my settings page?
Frame scenarioFrame = SettingsPage.Current.FindName("ScenarioFrame") as Frame;
if (scenarioFrame != null)
{
// Call ContinuationManager to handle continuation activation
continuationManager.Continue(continuationEventArgs, scenarioFrame);
}
}
Window.Current.Activate();
}
Thanks.
When your OnActivated is called if you know you always want to go to the SettingsPage then all you need is this code:
Frame rootFrame = CreateRootFrame();
await RestoreStatusAsync(e.PreviousExecutionState);
if (rootFrame.Content == null)
{
rootFrame.Navigate(typeof(SettingsPage));
}
That code creates the applications root frame, and tells it to navigate to that specific page.
The code after this uses ContinuationManager. This is a mechanism set up to call into the page to let it know it is coming back from a AndContinue method. This will allow the page to do any functionality to occur for that Page.
FilePicker also has a ContinuationData property which you can set prior to calling the AndContinue method. This data is available in OnActivated via the IContinuationActivatedEventArgs.
This blog has a good description of the AndContinue Methods:
http://blogs.msdn.com/b/wsdevsol/archive/2014/05/08/using-the-andcontinue-methods-in-windows-phone-silverlight-8-1-apps.aspx