WordPress database error: [INSERT, UPDATE command denied to user '51213-2'@'10.10.20.86' for table 'wp_options']
INSERT INTO `wp_options` (`option_name`, `option_value`, `autoload`) VALUES ('_transient_doing_cron', '1714608743.8389949798583984375000', 'yes') ON DUPLICATE KEY UPDATE `option_name` = VALUES(`option_name`), `option_value` = VALUES(`option_value`), `autoload` = VALUES(`autoload`)


Warning: Cannot modify header information - headers already sent by (output started at /home/lexiqued/www/WordPress/wp-includes/wp-db.php:1502) in /home/lexiqued/www/WordPress/wp-includes/feed-rss2.php on line 8
Jonathan ANTOINE – Jonathan ANTOINE's thoughts http://www.jonathanantoine.com Yet another blog about... Thu, 26 Jan 2017 11:08:51 +0000 en-US hourly 1 https://wordpress.org/?v=5.5.3 #Xamarin : how to easily use the Picasso SDK and #MvvmCross to display efficiently images in your #Android Apps http://www.jonathanantoine.com/2017/01/26/xamarin-how-to-easily-use-the-picasso-sdk-and-mvvmcross-to-display-efficiently-images-in-your-android-apps/ Thu, 26 Jan 2017 10:18:56 +0000 http://www.jonathanantoine.com/?p=1612 Picasso is a great open-source SDK which let you display images efficiently on Android. I wanted to use it in my MvvmCross app because it really helps you having great display performances especially on list.

I have my images available as a remote HTTP URL in my ViewModel and I wanted to do this the easy and fast way. I then created a target binding !

MvvmCross lets you create your own target binding by following these steps :

  1. Create an new class which inherits from MvxAndroidTargetBinding.
  2. Register this binding using the name you want in your Setup class.
  3. Use this new binding target

Creating the target binding

You simply have to inherits from the asbstract class MvxAndroidTargetBinding and implements the SetValueImpl method which will set the value (provided as an arg) to the target element (provided as an arg too).

In our case, I use Picasso to the bitmap on an ImageView :
[csharp]
public class ImageUrlToLoadBinding : MvxAndroidTargetBinding
{
public ImageUrlToLoadBinding(View target) : base(target) { }

public int PlaceHolderToUse { get; set; }

protected override void SetValueImpl(object target, object value)
{
var imageView = (ImageView)target;
Picasso.With(imageView.Context)
.Load(value as string)
.Into(imageView);
}

public override Type TargetType => typeof(string);
}
[/csharp]

Registering the target binding

In your Setup class, you have to register this custom binding using the name you want. This name will be the one used as a Target in your MvxBind attributes. To do this, you have to override the FillTargetFactories method.

In our case, I use “PosterImageUrlToLoad” as a key :
[csharp]
protected override void FillTargetFactories
(IMvxTargetBindingFactoryRegistry registry)
{
// register custom binding here
registry.RegisterCustomBindingFactory<View>
("ImageUrlToLoad", v => new ImageUrlToLoadBinding(v));

base.FillTargetFactories(registry);
}
[/csharp]

Using the target binding

This is the easiest part because it’s a casual binding simpley using your “name” as a target. I removed all the other attributes in this example :
[xml]<ImageView
local:MvxBind="ImageUrlToLoad ImageUrlManager.FinalImageUrl"
/>[/xml]

Happy coding !

]]>
Reminder : Sqlite is already inside #Windows 10 – no need to include it in your #UWP apps ! http://www.jonathanantoine.com/2016/10/21/reminder-sqlite-is-already-inside-windows-10-no-need-to-include-it-in-your-uwp-apps/ Fri, 21 Oct 2016 18:30:38 +0000 http://www.jonathanantoine.com/?p=1602 I have read, as a maybe a lot of you, that Sqlite is now shipped with Windows 10 : it’s true. Let’s see how you can target it.

I am a big fan of the sqlite-net github project and I nearly alwayse include it’s 2 sources file in my projects needing to do some Sqlite. If youd dig in the source file, you will see that it declares a lot of DllImport using “sqlite3”. This mean that you have to include the sqlite3.dll in your app and that it will be shipped with it. Since the threshold version, you can use the version shipped with Windows10 by replacing all this “Sqlite3” by “winsqlite3”. That’s it !

winsqlite

Why you may want to do this

  • Your app package will be smaller.
  • Faster : the dll should be already loaded by the OS when you need it.
  • You won’t have to install the Sqlite VSIX package.
  • You will be on the same version of Sqlite than Windows (Youpi!).

Why you may NOT want to do this

  • You won’t be using the latest version of Sqlite. If you depend of the latest available fix, it won’t be available.
  • Sqlite may be updated by Windows and bring breaking changes to your app.

The full doc (for C++) is available on MSDN : https://msdn.microsoft.com/vi-vn/windows/uwp/data-access/sqlite-databases

Happy coding !

]]>
.NET : execute some non-thread-safe code without issue in parallel with AppDomains http://www.jonathanantoine.com/2016/10/12/net-execute-some-non-thread-safe-code-without-issue-in-parallel-with-appdomains/ Wed, 12 Oct 2016 17:00:58 +0000 http://www.jonathanantoine.com/?p=1588 Today I faced a specific need withing a WPF application: I have a well-tested and already in production code which works well for a given user and I need to create an application to execute the same “one-thread/context” code for a lot of users at the same time. The code uses a lot of static fields, properties and can’t be run as it is in different threads.

The solution I ended up with is to create an AppDomain by “worker” and to execute the already existing code in each one. The context will be unique in each AppDomain and I will be able to reuse my existing code.

To have this working I have to perform these steps:

  • Create a new class project “MaDllAPart” on which I add a reference to my existing code assembly.
  • Create a new class “StartPoint” in it which inherits from MarshalByRefObject. This will let it be called from another AppDomain (my new WPF application in this case).
  • Add an “Execute” Method to my StartPoint class which calls my legacy code.
  • Create an AppDomain by thread, instanciate a StartPoint in this AppDomain.
  • Instanciate a StartPoint in this AppDomain and call it’s Execute method.

structure

The code for the StartPoint class is very easy :

public class MonPointDentree : MarshalByRefObject
{
    public static string Context;

    public void Execute(string input)
    {
        // Task can't be marshalled : let's wait
        ExecuteAsync(input).Wait();
    }

    private async Task ExecuteAsync(string input)
    {
        Debug.WriteLine("[BEFORE] " + Context);
        Context = input;
        Debug.WriteLine("[AFTER] " + Context);

        // call my legacy code here
    }
}

The “MaDllAPart” is added as a reference to the WPF project : this let’s me create an instance of StartPoint without special configuration from my side. Be sure to use the full name (with the namespace) of the instanciated type.

private static void LaunchProcess()
{
    for (int i = 0; i < 10; i++)
    {
        var domain = AppDomain.CreateDomain("MonAppDomain_" + i);

        var startPoint = (MonPointDentree)domain
            .CreateInstanceAndUnwrap("MaDllAPart", "MaDllAPart.StartPoint");

        startPoint.Execute("module " + i);
    }
}

Happy coding !

]]>
#HoloLens : launch a 3D (Holograms) app from a 2D #XAML app and going back to it #UWP http://www.jonathanantoine.com/2016/06/29/hololens-launch-a-3d-holograms-app-from-a-2d-xaml-app-and-going-back-to-it-uwp/ http://www.jonathanantoine.com/2016/06/29/hololens-launch-a-3d-holograms-app-from-a-2d-xaml-app-and-going-back-to-it-uwp/#comments Wed, 29 Jun 2016 06:47:02 +0000 http://www.jonathanantoine.com/?p=1573 In this blog post I will show you how to create a 2D #XAML app which will be able to display a 3D view (holograms) and then how to go back to the 2D view from the 3D view.

We wil do this using DirectX and Unity.

As you can see in this video, the “context” of the leaved Windows is kept : the scroll position does not change.

Opening another Windows from a n UWP app

Since a long time now, you can open a new Windows from a Windows Store app (UWP or Universal). For instance, the Mail app does this to let you edit an email in another dedicated window.

To perform this, you have to ask the SDK to create a new View (CoreApplicationView) which maps to a Window (CoreWindow) and an associated Dispatcher. This last point is interesting because you have to be very careful, when you share your ViewModels between windows, to be on the good Dispatcher when raising INotifyPropertyChanged event or doing some UI-related work.

Here is the code to create a Window :

// récupération de l'id courant pour usage ultérieur
var appViewId = ApplicationView.GetForCurrentView().Id;

//Create a new view \o/
CoreApplicationView newCoreAppView = CoreApplication.CreateNewView();

await newCoreAppView.Dispatcher.RunAsync(
    Windows.UI.Core.CoreDispatcherPriority.Low,
     () =>
     {
         //Get the created Windows
         Window window = Window.Current;
         ApplicationView newAppView = ApplicationView.GetForCurrentView();

         // create a new frame and navigate to the page
         var secondFrame = new Frame();
         window.Content = secondFrame;
         secondFrame.Navigate(typeof(MainPage));

         // activate the new Window
         window.Activate();

         // make the new window standalone
         ApplicationViewSwitcher.TryShowAsStandaloneAsync(newAppView.Id,
             ViewSizePreference.UseMore, appViewId, ViewSizePreference.Default);
     });

By providing no argument to the CreateNewView method, we ask the XAML framework to create and manage a XAML UI.

We could also provide an argument of type IFrameworkViewSource to be able to have our own Window managed by our code. This is what DirectX does and it will let us create holograms !

Displaying a 3D DirectX view from the 2D view

By using the “HolographicDirectXApp” Visual Studio sample, I have all I need to create and display a 3D rotating cube by. The generated code creates an instance of IFrameworkView using DirectX. The sample use SharpDX, some C# classes and shaders that I can simply copy/Paste directly in a new XAML UWP project.

Capture

I then only have to use the previous snippet and ask it to use the DirectX AppView.

I have to carefully :

  • keep an instance of my AppViewSource : if it’s garbage collected, my 3D view will disappear.
  • Activate the created Window for the DirectX view.

Of course, as all 3D holographic view, my start screen and the 2D View will disappear to let only the 3D objects in my space.

Capture2

Displaying a 3D Unity view from the 2D view

An Unity app being an UWP app the code to write will be very similar. We will only have to customize the generated Unity code to stay in a 2D World instead of going directly to the 3D exclusive View.

To be in the right configuration, I generate a XAML project instead of a Direct3D player in Unity. I then have this :

  • Unity initialization is done in the App class.
  • A MainPage XAML app which finish the initialisation and is the first page navigated to.

To have a “standard” Xaml project, I then perform these modifications :

  • I create a XAML “BlankPage” named StartupPage.
  • I navigate to this page instead of MainPAge. I then stay in a 2D classic XAML context and I can build my application around it.
  • I move the use of the AppCallbacks class from the App.cs class to the existing MainPage.

 

The next steps are easy : I create a new Window, add a frame in it and navigate to the MainPage. I use exactly the same snippet as before and I only have to register an event handler to the activation of the created Window to be able to initialize Unity then. I also store the main view’s Id for further use.

private async Task CreateNewHoloWindowAsync()
{
    var appViewId = MainAppViewId = ApplicationView.GetForCurrentView().Id;
 
    var _newCoreAppView = CoreApplication.CreateNewView();
 
    await _newCoreAppView.Dispatcher
        .RunAsync(CoreDispatcherPriority.Low,
      async () =>
      {
          var frame = new Frame();
          Window.Current.Content = frame;
          frame.Navigate(typeof(MainPage));
 
          var res = await ApplicationViewSwitcher.TryShowAsStandaloneAsync(
              ApplicationView.GetForCurrentView().Id,
              ViewSizePreference.Default, appViewId,
              ViewSizePreference.Default);
 
          _newCoreAppView.CoreWindow.Activated += WindowActivated;
 
          _newCoreAppView.CoreWindow.Activate();
      });
}
 
private void WindowActivated(object sender, WindowActivatedEventArgs e)
{
    if (e.WindowActivationState == CoreWindowActivationState.CodeActivated
        || e.WindowActivationState == CoreWindowActivationState.PointerActivated)
    {
        AppCallbacks.Instance.SetInitialViewActive();
        // Only need to mark initial activation once so unregister ourself
        CoreWindow coreWindowSender = sender as CoreWindow;
        coreWindowSender.Activated -= WindowActivated;
    }
}

Going back to the 2D View

To go back to the 2D XAML view, you have to use the ApplicationViewSwitcher class and ask it to go switch back to the main Window.

I provide my Unity’s code an Action (GoBackToEarth.CloseThisHolographicView) it can call when needed.

// let's capture the dispatcher of the current view
var dispatcher = Dispatcher;
 
GoBackToEarth.CloseThisHolographicView = () =>
{
    // be sure to be on the Window's Dispatcher
    dispatcher.RunIdleAsync(async _ =>
    {
        // go back to the main Window
        await ApplicationViewSwitcher.SwitchAsync(StartupPage.MainAppViewId);
 
        // we close the 3D holographic Window
        Window.Current.Close();
    });
};

Happy coding !

]]>
http://www.jonathanantoine.com/2016/06/29/hololens-launch-a-3d-holograms-app-from-a-2d-xaml-app-and-going-back-to-it-uwp/feed/ 13
#Windows app bundles and the ‘Subsequent submissions must continue to contain a Windows Phone 8.1 appxbundle’ error message http://www.jonathanantoine.com/2016/04/12/windows-app-bundles-and-the-subsequent-submissions-must-continue-to-contain-a-windows-phone-8-1-appxbundle-error-message/ Tue, 12 Apr 2016 08:28:39 +0000 http://www.jonathanantoine.com/?p=1555 Some days ago when uploading my Windows app to the Store, I’ve got a strange error message : “A previous submission for this app was released with a Windows Phone 8.1 appxbundle. Subsequent submissions must continue to contain a Windows Phone 8.1 appxbundle.”. Here’s how I fixed it !

About appxbundle

When you build an app, you can choose to translate it and add ressource dedicated to a special environments. Images/Logo specific to each pixel density plateau is one example of it. If you create bundles, your final package uploaded on the Store will be one “main” package and satellite package for each “specific target”.

It also means that the user will download only what is necessary to their devices : less bandwith used, smaller apps : happy users !

Creating app’s bundle is easy, in the last step of the Visual Studio package wizard, you choose either “If Necessary” or “Always”.
appbundle

Choosing to use app bundles has some consequences. The one which I was not happy with was that you won’t be able to let the user choose the language of your app since only the languages installed on it’s device will be available.

In my last update of TV Show Tracker, I wanted to let this freedom to my users so I used the wizard and choose to never create a bundle. I uploaded my package to the Store and I then get the previously mentionned error 🙁
error

Creating my own appbundle

The solution is then to create my own app bundle with the SDK tools and upload it to the Store.

Here are the steps :

  1. Create a package using Visual Studio without app’s bundle.
  2. Go to the created package folder and find the appx file (it can be in a subfolder).
  3. Copy this file in a separate folder, all alone.
  4. Use the MakeAppx tool to create a bundle aiming this directory.
  5. Upload the created bundle to the Store.
makeappx bundle /p NameOfTheCreatedBundle.appxbundle /d FolderWithTheAppxInside

The name of the bundle can be anything as the name of the folder with the appx inside.

What did I lost in the process ?

The whole app with all ressources will now be downloaded by my users. This can be frightening : how much more will they have to download ? Let’s take a look inside the app bundle…

zip

So an user on a standard density pixels, english phone will now download the not used “scale-140” assets, the “scale-180” assets and french language : 300 more kb –> 2,85 %. So for 2,85% more package size, my user will be able to choose the language of their app. That’s ok for me 🙂

Happy coding !

]]>
WinRT exceptions : how to know what the hexadecimal error code means http://www.jonathanantoine.com/2015/07/25/winrt-exceptions-how-to-know-what-the-hexadecimal-error-code-means/ http://www.jonathanantoine.com/2015/07/25/winrt-exceptions-how-to-know-what-the-hexadecimal-error-code-means/#comments Sat, 25 Jul 2015 10:11:08 +0000 http://www.jonathanantoine.com/?p=1542 When working with the WinRT SDK you somethimes get exceptions from it with only an hexadecimal code to help you understand what the error is. Often, when you look for it on Google/Bing, you end with no help and no way to fix the error. There is a way to know the associated error message !

I am talking about this kind of error messages : “Exception thrown at 0x77694598 (KernelBase.dll) in MonAppli.Windows.exe: 0x40080201: WinRT originate error (parameters: 0x80072F19, 0x00000067, 0x0519EE60).” I looked for every hexadecomal code without success.
Excception

To get the message associated with this error, follow this procedure :

  • Activat the native debugger : in the properties of your project, is at the end of the debug tab.
  • Launch your app with the debugger attached and produced the exception.
  • Copy the third hexadecimal code in the exception Windows (0x0519EE60 here).
  • Click on Break.
  • Open the “Memory 1” Windows. It’s only available in Debug mode in this menu : “Debug > Windows > Memory > Memory 1”
  • Paste the value in the adress text box and press the enter key
  • The description is available at the right 🙂

exception2

]]>
http://www.jonathanantoine.com/2015/07/25/winrt-exceptions-how-to-know-what-the-hexadecimal-error-code-means/feed/ 1
Windows Phone : localize your App name http://www.jonathanantoine.com/2013/12/27/windows-phone-localize-your-app-name/ http://www.jonathanantoine.com/2013/12/27/windows-phone-localize-your-app-name/#comments Fri, 27 Dec 2013 17:27:10 +0000 http://www.jonathanantoine.com/?p=1522 When you build a Windows Phone App, you for sure take some time to translate it in several language. By default there is no easy way to translate the app name but you can do it. Here is a quick “how-to” !

  1. Download this project and add it to your solution : http://code.msdn.microsoft.com/wpapps/Language-Neutral-Resource-5894846e.
  2. Edit the string table in the AppResLib.rc file to set your app name, etc.
  3. Build this project and copy the resulting dll in your WP project. This will be the default values (neutral language)
  4. Change the values in the AppResLib.rc file for a specific language (for example french) and build again the project.
  5. Rename the resulting dll to AppResLib.dll.040c.mui and copy it at the root of the WP project, next to the dll. The “04OC” is specific to “French” and should be set to the value matching the target language. A full list is here : http://msdn.microsoft.com/en-us/goglobal/bb964664.aspx
  6. Do it again for as much language you want
  7. Select all the *.mui files and the AppResLib.dll file and set their build type to content in the properties Windows.
  8. Update your WMAppManifest.xml file and set the app name to this value : @AppResLib.dll,-100 . The value will then be taken for your file, depending of the user language, at the offset 100 in the string table.

reslLib

manifest

Not really obvious but this works fine 🙂

If you want to see this feature in action, it will soon be available in our last app “Say it With Flowers” !

PS: the whole procedure is describe in depth on MSDN but I am sure you love this recap 🙂

PS2: the localized app name won’t be displayed on the Store page because of a bug in the Store : http://blog.webrox.fr/?p=61

]]>
http://www.jonathanantoine.com/2013/12/27/windows-phone-localize-your-app-name/feed/ 2
WinJS 2.0 / IE 11 : the new and shiny MutationObserver object http://www.jonathanantoine.com/2013/10/28/winjs-2-0-ie-11-the-new-and-shiny-mutationobserver-object/ http://www.jonathanantoine.com/2013/10/28/winjs-2-0-ie-11-the-new-and-shiny-mutationobserver-object/#comments Mon, 28 Oct 2013 06:56:15 +0000 http://www.jonathanantoine.com/?p=1511 Let me introduce you a new feature of Internet Explorer 11 which is available in your Windows 8.1 apps too : the MutationObserver. This object lets you observe the changes on any HTML element of your DOM.

You may already know these monitoring events available before and which are now no more supported :

  • DOMNodeInserted
  • DOMNodeRemoved
  • DOMSubtreeModified
  • DOMAttrModified
  • DOMCharacterDataModified

They have been replaced by the MutationObserver in IE 11 because they have several drawbacks:

  • They are standard JS events, so they bubble the whole DOM : bad for performance.
  • They may spam you because each change raise an event without batching : bad for performance.
  • They are synchronous and block your execution : bad for performance.
  • Did I tell you that there may be performance issues?

The MutationObserver fix these issues and is really easy to use :

  1. Create a mutation observer by giving a callback function as a parameter.
  2. Observe an element and specify “what to observe”
  3. Do something in the callback

Creating a mutation observer is easy as instantiating an object. The callback function takes 2 parameters : an object describing the change and the second one will be the MutationObserver.
[js]function mutationObserverCallBack(changes, mutationObserver) {/*…*/ }

//Creation of the observer
var observer = new MutationObserver(mutationObserverCallBack);[/js]

Then you can observe any html element by calling the observe function on the observer. This function takes as a second parameter a json object with the “monitoring” options. For example, you can monitor only the addition/removal of element on any of its children and any change of “class” :
[js]
var observer = new MutationObserver(mutationObserverCallBack);
observer.observe(element, {
attributes: true,
attributeFilter: ["class"],
childList: true,
subtree: true,
});
[/js]
There is a lot of possible configuration and you can find a full list on this MSDN page.

In the callback, you can explore the changes which is a list of the modifications. Each one has a type field and some properties (added nodes, old value, etc.) which let you know which change has been performed.
[js]function mutationObserverCallBack(changes, mutationObserver) {

changes.forEach(function (mutationRecord) {

console.log("Type of mutation: " + mutationRecord.type);

if ("attributes" === mutationRecord.type) {
console.log("Old attribute value: " + mutationRecord.oldValue);
}
});
}[/js]

changesMoniker

Additionnal links

This is a just a quick blog post of this good new API. You can find more information on these pages :

]]>
http://www.jonathanantoine.com/2013/10/28/winjs-2-0-ie-11-the-new-and-shiny-mutationobserver-object/feed/ 1
#WinRT : how to easily get the dominant color of a picture http://www.jonathanantoine.com/2013/07/16/winrt-how-to-easily-get-the-dominant-color-of-a-picture/ http://www.jonathanantoine.com/2013/07/16/winrt-how-to-easily-get-the-dominant-color-of-a-picture/#comments Tue, 16 Jul 2013 07:15:39 +0000 http://www.jonathanantoine.com/?p=1500 “Content before Chrome” is the Leitmotif of Windows Store Apps. You’ll usually end up using a lot of images in your app and getting the dominant color of a picture may actually be useful. My first attempt to achieve this was to get the bytes of the picture and calculate the average value. There is actually an easier and faster solution using the Windows Rutime API.

The GetPixelDataAsync method of the BitmapDecoder class lets you get the pixels of a given picture and you can apply transformations during the process. I will the simply ask it to resize the image to a simple unique pixel. The resulting pixel will be the dominant color of the image.

[csharp]
//get the file
var file = await StorageFile.GetFileFromApplicationUriAsync(myLocalImageUri);

using (var stream = await file.OpenAsync(FileAccessMode.Read))
{
//Create a decoder for the image
var decoder = await BitmapDecoder.CreateAsync(stream);

//Create a transform to get a 1×1 image
var myTransform = new BitmapTransform { ScaledHeight = 1, ScaledWidth = 1 };

//Get the pixel provider
var pixels = await decoder.GetPixelDataAsync(
BitmapPixelFormat.Rgba8,
BitmapAlphaMode.Ignore,
myTransform ,
ExifOrientationMode.IgnoreExifOrientation,
ColorManagementMode.DoNotColorManage);

//Get the bytes of the 1×1 scaled image
var bytes = pixels.DetachPixelData();

//read the color
var myDominantColor = Color.FromArgb(255, bytes[0], bytes[1], bytes[2]);
}

[/csharp]

The code is extremely simple: open the file, open its stream, create a BitmapDecoder, grab the pixels applying the transform and read the color.
dominant color

]]>
http://www.jonathanantoine.com/2013/07/16/winrt-how-to-easily-get-the-dominant-color-of-a-picture/feed/ 1
Windows 8.1 : let’s discover the Scheduler of #WinJS http://www.jonathanantoine.com/2013/07/02/windows-8-1-lets-discover-the-scheduler-of-winjs/ http://www.jonathanantoine.com/2013/07/02/windows-8-1-lets-discover-the-scheduler-of-winjs/#comments Tue, 02 Jul 2013 12:29:35 +0000 http://www.jonathanantoine.com/?p=1471 WinJSSchedulerWindows 8.1 comes with a new feature in the WinJS SDK : a scheduler. Let’s see what it is and how to use it!

In Windows 8, every job is nearly done as soon as you execute it. You could play with the msSetImmediate function but it was still a little mode “hack” than “code”.

With Windows 8.1, the SDK introduce a scheduler used by the whole WinJS framework. This scheduler helps you to define what is important (animations, visual feedback, manage user input) from what can be delayed (background work, data processing not used immediatly).

The goal is to let you build application which reacts immedialty to the user will.

What’s in it ?

Everything lives in the WinJS.Utilities.Scheduler namepsace and is written in javascript.
This namespace is often shortcuted “Scheduler” or “S” in the Microsoft samples.
[js]var S = WinJS.Utilities.Scheduler;[/js]

There is 4 importants objects to know :

  • WinJS.Utilities.Scheduler: the main namepsace with a lot of static function which lets you start and manage jobs
  • WinJS.Utilities.Scheduler.IJob : everything thing is a job. When you start a task/work using the scheduler, it returns you an IJob object on which you can call management methods.
  • WinJS.Utilities.Scheduler.IJobInfo : information passed to your work-function when executed.
  • WinJS.Utilities.Scheduler.IOwnerToken : you want to be the owner of a task and manage a group of jobs then use this.

How to use it (101) ?

Launching a job is as simple as providing a function :
[js]
var job = WinJS.Utilities.Scheduler.schedule(function willBeExecuted(){

//work to be done
});
[/js]

There is some optional parameters that can be set too : a priority (default is WinJS.Utilities.Scheduler.Priority.normal.), a this parameter which will be set when the function is executed and name (useful when debugging):
[js]
var whoAmI = {};
var job = WinJS.Utilities.Scheduler.schedule(function willBeExecuted(){

//work to be done
} , WinJS.Utilities.Scheduler.Priority.normal, whoAmI, " I am the job name" );
[/js]

The returned object is a IJob object and you can call some function on it to cancel it’s scheduling, pause it, resume it and have some information like the name, the priority, the owner, etc.
[js]
//create a job
var job = WinJS.Utilities.Scheduler.schedule( /* …*/);
//pause the job
job.pause();

//resume it in 5 secs
WinJS.Promise.timeout(5000).then(job.resume);

//reads the name of the job
var name = job.name;
[/js]

IJobInfo and yielding

In this case “yielding” means “let other task more important than me start and do their job while I am executing and pause me”.
Let’s assume that you have a job which takes 10 seconds to be done and that you can split it in 10 parts.
Then you can launch the job with the scheduler, do the first part and tells it : do something else (other jobs with higher priority) if necessary then call me back. The Scheduler will then manage this process for you.

When your job is executed, a parameter is actually provided and it implements the IJobInfo interface. This jobInfo object has 2 important functions and 1 important field :

  • setPromise: calling it providing a function tells the scheduler to wait for this promise before to call you back. If you need to download locally an internet resource, the Scheduler does not need to call you before and you can set a promise to wait for the download to be done.
  • setWork : calling it providing a function tells the scheduler which function to call when it wants to continue your processing (after the execution of more importants tasks).
  • shouldYield : read this to know if the function should yield : if true, you set the next function to call using the setWork function and you returns. If false, you do your job.

So how do we implement this feature ? By creating a processing function which will process each part in a loop. At each cycle, we will check if we have to yield. If so, we tells the scheduler to call us back when it wants to restart our process. If the process is done (10 parts processed) then we just returns.

Here is how I will implement this “10 parts processing”.
[js]var partProcessed = 0;

function executeYieldingTask() {

// schedule some work
S.schedule(function myScheduledJob(jobInfo) {

//Process the 10 parts
while (partProcessed < 10) {

//check if I have to yield :new job with higher priority
// may have been scheduled
if (jobInfo.shouldYield) {

//tells the Scheduler to execute myScheduledJob
// when it’s done executing higher priority task
jobInfo.setWork(myScheduledJob);

//we yield so we exit the ‘process loop’
break;

}
else {
/* process the part partProcessed */
partProcessed = partProcessed + 1;
}
}
}, S.Priority.idle);
}

[/js]

The IOwnerToken interface and how to use it

IOwnerToken is an interface which represents the owner of a job. By owner it means “master” : the one who controls and manage it.
A token can be set to multiple jobs at once and there is one function on this interface : cancelAll. This function simply cancel all the jobs owned by the token.

To create a token, you have to call the createOwnerToken function. You can then assign it to created job.
[js]
//create a token
var ownerToken = WinJS.Utilities.Scheduler.createOwnerToken();

//create jobs
var job1 = WinJS.Utilities.Scheduler.schedule( /* …*/);
var job2 = WinJS.Utilities.Scheduler.schedule( /* …*/);

//Be in control
job1.owner = ownerToken ;
job2.owner = ownerToken ;

//Cancel the jobs at once :
ownerToken.cancelAll();
[/js]

This token is then really useful when you want to manage a group of jobs at once. Create an owner, if the user do something else, goes to another page : you cancel all the task at once and retrieve some CPU juice.

Some useful functions

Now let’s discover some useful functions when playing with jobs and the scheduler.

  • requestDrain : use this function if you want to be sure that all scheduled jobs at a given priority are over. Simply pass the targeted priority, it returns a promise which can be use to know the completion of the “error state” of the queue processing
  • retrieveState : you need to dump the schedule queue for debug purpose ? Use this function :). It dumps the name, the id, the priority of the tasks, etc.
  • schedulePromiseXXX : there is a lot of functions with similar names(schedulePromiseAboveNormal, etc.). These functions takes a promise as a parameter. It assures that the completion/error handler is processed on the scheduler with the given priority. If you want a completion handler tob be processed as soon as the promise is done, then use schedulePromiseHigh.

Here are some code example :
[js]
//requestDrain example
var drainPromise = WinJS.Utilities.Scheduler.requestDrain(priority, name);

drainPromise.done(
function complete(){console.log("queue drained");},
function error(){ });

//retrieveState example :
var S= WinJS.Utilities.Scheduler;
S.schedule(function () {/* */ }, S.Priority.aboveNormal,null,"a task name");
S.schedule(function () {/* */ }, S.Priority.idle,null, "infinite square name");
S.schedule(function () {/* */ }, S.Priority.belowNormal,null,"another task name");

var state = WinJS.Utilities.Scheduler.retrieveState();
/*
state looks like this :
Jobs:
id: 22, priority: aboveNormal, name: a task name
id: 24, priority: belowNormal, name: another task name
id: 23, priority: idle, name: infinite square name
Drain requests:
None
*/

//schedulePromiseXXX example
var dldPromise = WinJS.xhr({url:’www.infiniteSquare.com’});
WinJS.Utilities.Scheduler.schedulePromiseHigh(dldPromise)
.then(function(xhrResult){
/* process interesting content */
});

[/js]

Regards.

]]>
http://www.jonathanantoine.com/2013/07/02/windows-8-1-lets-discover-the-scheduler-of-winjs/feed/ 2