Showing posts with label Execution Model. Show all posts
Showing posts with label Execution Model. Show all posts

Monday, 2 June 2014

Pitfalls of adding WP8.1 support to a universal app (Part 1 of N)

As part of our continuing port from Windows 8.1 to WP8.1 of Surface Level, I’ve just recently tracked down a problem thrown during suspension.

We’d already written quite a few classes that would act as a base class, and as a result, I implemented a partial method which I could call for certain tasks.  One of these tasks was registering our Suspension handler.

The bug I was seeing was an end of file reached while reading back our state file, which we use when we resume.  But there were two problems

1.  I kept getting odd suspension manager exceptions in my crash logs.
2.  The suspended handler never seemed to be called anyway.

Item 2 was the first to solve.  It appears that like W8.1, apps aren’t suspended when run in the debugger.  The only problem was, I couldn’t find the UI to shut it off.

Well, eventually I found it here on the Debug Location toolbar:

image

Clicking Suspend actually caused my suspension to run (twice in fact)

The first crash was caused by the state file being read only (a side effect of running suspension twice).  It turns out that when I added the WP8.1 project, the wizard had added a second call wiring up the suspension code, which I hadn’t spotted.  Removing the duplicate wiring allowed me to get suspension working properly.

Friday, 30 December 2011

Tombstoning and Mango: Something’s Awry!

I’ve wasted another day.

I’ve been trying without success to understand what’s happening with Tombstoning, and why my properties which are data bound are not being updated.

To cut a long story short, you can reproduce this using Matt Lacey’s Tombstone Helper Toolkit as follows:

First, download the latest source from CodePlex.

Build for OS 7.1, which requires you to modify the Demo Projects WMAPPManifest.xml file to have the correct AppPlatformVersion 7.1, or you get an error from Microsoft.Phone.PreImport.targets ValidateWMAppManifest rule.

Go to the Debug tab of the demo, and switch on Tombstoning.

Build and run the file, and go to the TextBox demo, and verify that if you change field 1, and navigate away and back, that its value returns.

Now make the following changes:

On line 30 of TextBoxes.xaml, change the line to this, so it’s DataBound as follows:

<TextBox Name="first" Text="{Binding Path=UserName, Mode=TwoWay}"/>


Now, add this to the top of TextBoxes.xaml.cs, inside the namespace declaration.  It’s based on Jesse Liberty's ViewModel here:


public class MainPageViewModel : INotifyPropertyChanged {
private string _userName;
public string UserName
{
get { return _userName; }
set { _userName = value; NotifyPropertyChanged("UserName"); }
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string propName)
{
if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propName)); }
}

public MainPageViewModel()
{
UserName = "I AM SAM";
}
}


Finally, modify Matt’s TextBoxes constructor to set my ViewModel as the DataContext:


public TextBoxes()
{
DataContext = new MainPageViewModel();
InitializeComponent();
}

If you now run the code, and change “I AM SAM” to “SAM I AM”, navigate away, and then back, you’ll see that the name is not replaced.

 

I’ve found a bodge, based on what I read here on the WP7 forums:  Change OnNavigatedTo like this:

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
// Uncomment the next line for changes to be reloaded
// Loaded += (s, ea) =>
{
this.RestoreState();
};
}

 



If you uncomment the Loaded+= line, the code will now work as expected.


Clearly there’s something odd going on with Mango here, as I’ve seen this in my own simplistic implementation where I set the Text property of a TextBox directly without all the framework like this:


Long.Text = (string)State["Longitude"];


and it too does not get updated correctly.

Wednesday, 21 December 2011

Fast and Loose with WP7 Mutex

While trying to figure out how to synchronize access between my ScheduledAgent and my main program, I started to investigate how Mutex objects behave.

Normally on Windows, when a Mutex is abandoned, an exception is raised when the Mutex is next acquired.  After searching online, I failed to find a description of what happens, particularly if you are holding a Mutex when WP7 decides to kill your process.

Here’s my sample I dropped onto a phone page:

private void OnLoaded(object sender, RoutedEventArgs e)
{
m = new Mutex(false, "KeepOff");
bgw = new Thread(new ThreadStart(bgw_DoWork));
bgw.Start();
try
{
Thread.Sleep(500);
m.WaitOne();
Thread.Sleep(500);
}
catch (Exception ex)
{
}
m.ReleaseMutex();
}

void bgw_DoWork()
{
m.WaitOne();
Thread.Sleep(5000);
Thread.Sleep(0);

}


Surprisingly, when the thread exits, the Mutex is acquired by the code in the try block, and no exception is raised.  I also tested the behavior in my ScheduledAgent, and in that circumstance, the Mutex is also released when the thread is terminated.


Eventually, I did find a reference to the behavior on the phone, but rather than being on WaitOne where I thought it belonged, it’s here: ReleaseMutex Method


Now , I wouldn’t recommend being this sloppy with your Mutex objects, but it looks like for now at least we can assume WP7 will clean up after us.


Peter Torr points out WaitOne might be dangerous, particularly in light of FAS (Fast Application Switching) if it doesn’t include a timeout.  I’ll look into that more in another post.

Thursday, 15 December 2011

ScheduledAgent on WP7 and Asynchronous Events

While working on my LiveTiles, I’ve had a few suggestions that I should wait for an event to occur on loading images.  That’s actually not the problem from what I can tell, but it raised an interesting question.

Let’s say that that I implement my OnInvoke like this:

protected override void OnInvoke(ScheduledTask task)
{
MyEventRaisingObject obj = new MyEventRaisingObject();
obj.SomeAsynchronouslyRaisedEvent += (sender, e) =>
{
// do some work to handle the event, and update our tile
// for example, fetch an xml feed asynchronously
}
NotifyComplete();
}


It looks to me like the OnInvoke will return before my event gets a chance to execute, or in any case I’ll hit my NotifyComplete call.

 

How does one effectively spin until an event has been raised without blocking the thread the object was created on?  Sure I can do this:

 


AutoResetEvent ev1 = new AutoResetEvent(false);
AutoResetEvent ev2 = new AutoResetEvent(false);

...

WaitHandle.WaitAll(new WaitHandle[] { ev1, ev2});

But won’t that block the thread we’re on?

-- update 16 dec --


Don’t even think about using the AutoResetEvent trick above. 


I tried it to wait for my images to be loaded into a BitmapSource, but it seems that the load is done on the UI thread, and as a result, I block the thread waiting for an event to be raised to signal my AutoReset, so that the event can never be raised.

Sunday, 18 September 2011

Tombstoning and Trial Mode for Window Phone 7

Yesterday, I attended the Windows Phone developer camp in London, courtesy of Microsoft.  I took the opportunity while there to add trial functionality to my two existing WP7 apps.

I based my code on the information found here:

http://msdn.microsoft.com/en-us/library/hh286402(v=VS.92).aspx

I naively bound some of my UI elements to be visible when the Trial Mode flag was set.  Because I was running in the debugger, and I tried to purchase the application, my app was tombstoned.  When the app is resurrected, Trial Mode defaults to true.

However, my debug version prompts as to whether to run in TrialMode or not, and as a result when the app is resurrected, it has already bound to the TrialMode flag.  Therefore you must implement INotifyPropertyChanged to broadcast the information.