piątek, 13 stycznia 2012

Notatki o Windows 8 - odc. 20

Koncepcje i architektura aplikacji Metro - Windows Runtime & .NET dla aplikacji Metro.

With Metro style apps, all apps are installed per user; they install, update, and uninstall cleanly; and they don’t change the operating system in an irreversible way.

What works on Windows 7 works even better with Windows Developer Preview. In fact, the APIs that we've added for Metro style apps - such as those for sensors - are available to desktop apps too. The Windows Software Development Kit (SDK) for Metro style Apps has a much-reduced API surface area, composed primarily of the new Windows Runtime (WinRT) API, plus a small subset of essential Win32 and .NET APIs.

Native APIs projected into C++, C#, Visual Basic, and JavaScript. Third parties can supply environments for additional languages.

Licensed per user with automatic roaming app settings via the cloud.

For Metro style apps, that is, the Windows Store is the only means of general distribution (enterprise customers and developers can bypass the store to side-load apps).

Users can create content tiles that link directly into specific parts of an app.

Suspended apps remain in memory and can be quickly resumed if the user switches back to them, they’re needed to fulfill a task (like providing search results or a sharing service), or they’ve asked to be awakened in response certain events like a timer or network activity.

If the system needs to free memory, it can unload suspended apps, knowing that the app can reload its saved state when it starts up again to bring the user right back to where they left off.

Selective app features, such as music, voice-over-IP, and data transfer, can continue running in background mode (subject to user approval).

By default, an app can access only its AppData folder (including local, roaming, and temp sub-folders, all of which are deleted when a user uninstalls an app).

Finally, app container environment provides additional runtime protection by isolating apps from one another. This protects apps from various forms of attack by other apps, such as defacement, intercepting input (click jacking), and impersonation.

Starting with Windows Developer Preview, new APIs are published through a metadata-based mechanism in which classes, interfaces, properties, events, and so on are directly projected into any number of language environments.  Third parties can use the metadata to provide native access through other languages.

What’s especially exciting is that underlying structures of COM (and DLL exports) are mapped to the natural structures of a particular language. For example, although the raw mechanism for class instantiation uses COM’s CoCreateInstance function, the Windows Runtime allows different languages to use their new operators instead. Similarly, where APIs themselves return error information in HRESULTs (which are typically difficult to program around), Windows Runtime turns them into exceptions. The result is that all Windows Runtime APIs, and custom (third-party) APIs implemented with this model, are immediately available to all languages without any additional work.

JavaScript uses the standard HTML5+CSS3 presentation layer because the hosting environment for these apps is built on the same rendering engines as Internet Explorer.

The Windows Runtime

The Windows Runtime packs core functionality for building Metro style apps into a small API surface. Your Metro style apps can also use the subset of traditional Win32, Component Object Model (COM), and .NET Framework APIs that is included in the Windows Software Development Kit (SDK) for Metro style Apps.

The Windows Runtime is supported starting with Windows Developer Preview. Your Metro style apps run equally well on ARM, x86, and x64 architectures.

The Structure of the WinRT

The Windows Runtime is exposed using API metadata (.winmd files). This is the same format used by the .NET framework (Ecma-335). The underlying binary contract makes it easy for you to access the Windows Runtime APIs directly in the development language of your choice. The shape and structure of the Windows Runtime APIs can be understood by both static languages such as C# and dynamic languages such as JavaScript. IntelliSense is available in JavaScript, C#, Visual Basic, and C++.

Each .winmd file exposes one or more namespaces. These namespaces are grouped by the functionality that they provide. A namespace contains types such as classes, structures, and enumerations. A type contains members such as methods, properties, and fields.

WinRT programming concepts

Activatable classes

Creating an instance of a Windows Runtime class is known as activation. The way you activate a class depends on the programming language you're using. When you activate a class, Windows checks whether you can access the requested user data or system resources. If additional access is needed, you must specify the required capabilities in the package manifest for the app. There's no need to manage the lifetime of underlying object. Windows releases the object when you're finished with the last of its class instances that you've activated.

Events and delegates

Asynchronous operation

The Windows Runtime uses the asynchronous model to drive the workload of the UI thread and help you deliver a responsive app. The general pattern supported by the Windows Runtime is to get the result of the asynchronous call using the Completed and GetResults methods. In C#, you can use the async and await keywords. In JavaScript use the then syntax.

Capabilities

Contracts

Custom components

You can build reusable libraries for use with your apps as custom components. Build your custom components with C#, Visual Basic, or Microsoft Visual C++ and use them from JavaScript or any other supported language in your apps - just as you would call a Windows Runtime API. Your custom components are included in the package for your app.

Asynchronous patterns in the WinRT

You can start a long-running task without blocking the UI thread, and you can receive the results of the task at a later time. You can cancel tasks and receive progress notifications as tasks run in the background. You don't need to manage threads explicitly or interact directly with the underlying concurrence implementation.

Request release of resources by using a close function.

Asynchronous patterns in JavaScript

In JavaScript, asynchronous programming follows the Common JS Promises/A proposed standard and works with toolkits like jQuery, Dojo, and Windows Library for JavaScript.  

tempFolder.createFileAsync("tempfile.txt").then(function (tempFile) {

    console.log("Created temp file at: " + tempFile.path);

});

=

// Get a promise to create the temp file.

var promise = tempFolder.createFileAsync("tempfile.txt");

 

// Assign the completion handler function.

promise.operation.completed = function (asyncOp) {

    var path = asyncOp.operation.getResults().path;

    console.log("Created temp file at: " + path );

};

   

// Start the asynchronous operation.

promise.operation.start();

You can chain asynchronous operations by calling the then function on the promise that is returned by the previous then function.

You can use the then function to assign the handler functions for progress notifications and error handling.

The Windows Library for JavaScript is a toolkit for asynchronous programming. It's based on the Common JS Promises/A proposed standard and works with toolkits like jQuery and Dojo.

A Promise object represents a promise for a future value that will be fulfilled eventually. You get a Promise object from a factory function, which by convention has a name that ends with "Async". The Promise object enables the promise contract for asynchronous operations like data binding and ListView data sources.

The Promise object provides static utility functions for working with promises of many kinds, including Promise and Windows Runtime async operations. For example, the join function enables composing multiple asynchronous operations that all need to complete before the next step in the algorithm executes.

In addition to sophisticated utilities, the Promise object enables easy implementation of your own asynchronous functions.

function pollAsync(f, interval) {

    //

    // Periodically run the function 'f' until it returns true. Once it

    // returns true, stop polling and fulfill the promise successfully.

    // If it throws an error, stop polling and fulfill the promise

    // with an error.

    //

    var token;

    return new WinJS.Promise(

        function (c, e) {

            token = setInterval(

                function () {

                try {

                    var result = f();

                    if (result) {

                        clearInterval(token);

                        c();

                    }

                } catch (ex) {

                    clearInterval(token);

                    e(ex);

                }

            },

                interval || 1000

            );

        },

        function () {

            // If canceled, clear the interval to stop polling.

            clearInterval(token);

        }

    );

}

 

// The startPolling function calls the poll function with

// a function that is invoked every 1000 milliseconds.

function startPolling() {

 

    pollAsync(function () { console.log("poll interval"); }, 1000).

        then(function () {

            console.log("polling canceled"); });

};

Asynchronous patterns in C#

In C#, asynchronous programming is based on the Task class and the await operator.

var tempFile = await tempFolder.CreateFileAsync("tempfile.txt");

=

StorageFileRetrievalOperation op = tempFolder.CreateFileAsync("tempfile.txt");

Task<StorageFile> task = op.StartAsTask<StorageFile>();

var tempFile = await task;

The await operator causes execution to transfer to the caller while the task runs in the background, and when the task completes, execution transfers back to the tempFile assignment in the CreateTempFileAsync method.

Asynchronous methods are for operations that don’t need a lot of thread time. If you need to move intensive work or unavoidable blocking calls from your thread, you should put them on the thread pool using the Task.Run method.

Asynchronous methods with progress and completion handling

DownloadOperation op = backgroundDownloader.StartDownloadAsync(uriContoso, tempFile);

 

// Assign delegates for the Progress and Completed notifications.

op.Progress = new AsyncActionProgressHandler<BackgroundDownloadProgress>(DownloadProgressEventHandler);

op.Completed = new AsyncActionWithProgressCompletedHandler<BackgroundDownloadProgress>(DownloadCompletedHandler);

 

// Start the asynchronous operation.

await op.StartAsTask();

 

void DownloadProgressEventHandler(

    IAsyncActionWithProgress<BackgroundDownloadProgress> action,

    BackgroundDownloadProgress progress)

{

    // Report progress on the asynchronous operation.

    // For example, you could update a ProgressBar control.

    Debug.WriteLine("Bytes retrieved: " + progress.BytesReceived);

}

 

void DownloadCompletedHandler(IAsyncActionWithProgress<BackgroundDownloadProgress> op)

{

    // Perform actions based on the completion status.

    if (op.Status == AsyncStatus.Error)

    {

        Debug.WriteLine("Error: " + op.ErrorCode);

    }

    else if (op.Status == AsyncStatus.Canceled)

    {

        Debug.WriteLine("Canceled");

    }

    else if (op.Status == AsyncStatus.Completed)

    {

        Debug.WriteLine("Download Completed");

    }

}

Asynchronous methods with anonymous delegates

You can track the progress and get detailed information about the outcome of an asynchronous operation by providing anonymous delegates.

    DownloadOperation op = backgroundDownloader.StartDownloadAsync(uriContoso, tempFile);

 

    // Assign delegates for the Progress and Completed notifications.

    op.Progress = delegate(

        IAsyncActionWithProgress<BackgroundDownloadProgress> action,

        BackgroundDownloadProgress progress)

    {

        // Report progress on the asynchronous operation.

        // For example, you could update a ProgressBar control.

        Debug.WriteLine("Bytes retrieved: " + progress.BytesReceived);

    };

 

    op.Completed = delegate(IAsyncActionWithProgress<BackgroundDownloadProgress> completedOp)

    {

        // Perform actions based on the completion status.

        if (completedOp.Status == AsyncStatus.Error)

        {

            Debug.WriteLine("Error: " + op.ErrorCode);

        }

        else if (completedOp.Status == AsyncStatus.Canceled)

        {

            Debug.WriteLine("Canceled");

        }

        else if (completedOp.Status == AsyncStatus.Completed)

        {

            Debug.WriteLine("Download Completed");

        }

    };

 

    // Start the asynchronous operation.

    await op.StartAsTask();

Asynchronous patterns in C++

In Visual C++, asynchronous programming is based on the IAsyncOperation<TResult> interface. The IAsyncOperation<TResult> interface represents an asynchronous operation that has a result of type TResult. You provide the code that executes asynchronously by providing an AsyncOperationCompletedHandler delegate.

In the Windows Developer Preview pre-Beta, the asynchronous programming pattern in Visual C++ requires direct manipulation of the IAsyncOperation<TResult>. Visual C++ Beta is expected to provide syntactic support that will greatly simplify consumption of asynchronous APIs.

auto fileOp = StorageFile::GetFileFromPathAsync("c:\\Temp\\text.txt");

fileOp->Completed = ref new AsyncOperationCompletedHandler<StorageFile^>([](IAsyncOperation<StorageFile^> ^operation) {});

fileOp->Start();

Asynchronous programming in JavaScript using promises

Avoiding synchronous execution in single-threaded languages like JavaScript is necessary in order to create apps that are responsive and high performing.

Promises in Windows Library for JavaScript however are independent of Windows Runtime and developers can readily use them when constructing their own pure JavaScript libraries.

confirm.show('Are you sure?' })

       .then(function (ok) {

            return ok

                ? doSomething()

                : dontDoSomething(); 

       });

 

function show(caption) {

    var ok = WinJS.Utilities.query('button#ok', element)[0],

        cancel = WinJS.Utilities.query('button#cancel', element)[0];

 

    // other setup, such as setting the caption

 

    return new WinJS.Promise(function (complete, error, progress) {

        ok.addEventListener('click', function () { complete(true); });

        cancel.addEventListener('click', function () { complete(false); });

    });

}

Advanced composition of promises

    var urls = [

        'http://www.cohowinery.com/',

        'http://www.fourthcoffee.com/',

        'http://www.wingtiptoys.com'

        ];

       

    // begin playing an animation here

 

    var promises = urls.map(function (url) {

        return myWebService.get(url);

    });

 

    WinJS.Promise.join(promises).then(function () {

        // end the animation here

    });

Access to user resources using the WinRT

Apps that declare the documentsLibrary capability cannot access the Documents library on Home Group computers.

Proximity. The devices attempt to use the communication technology that provides the best possible connection, including Bluetooth, WiFi, and the internet. This capability is used only to initiate communication between the devices.

Windows domain credentials enable a user to log into remote resources using their credentials, and act as if a user provided their user name and password. The defaultWindowsCredentials capability is typically used in line-of-business applications that connect to servers within an enterprise.

The privateNetworkClientServer capability provides inbound and outbound access to home and work networks through the firewall. This capability is typically used for games that communicate across the local area network (LAN), and for apps that share data across a variety of local devices. Apps must declare this capability to access shared folder resources like Universal Naming Convention (UNC) folders. If your app has specified musicLibrary, picturesLibrary, or videosLibrary, you do not need to use this capability to access the corresponding library in a Home Group.

The sharedUserCertificates capability enables an app to access software and hardware certificates, such as certificates stored on a smart card. This capability is typically used for financial or enterprise apps that require a smart card for authentication.

WinRT and the Windows API

The subset of the Windows API that can be used in a Metro style app is indicated in the header files in the Windows Software Development Kit (SDK) for Metro style Apps. Look for the following statements in the header files:

#pragma region Application Family

#pragma region Desktop Family

Devices

The following device APIs are supported: Win32 and COM for Metro style apps (devices).

No alternatives: FAX, serial and parallel ports.

Graphics

The following features are at least partially supported:

  • Direct2D
  • Direct3D 11
  • DirectWrite
  • DXGI
  • WIC
  • XPS

Multimedia

The following features are at least partially supported:

  • Media Playback
  • Media Foundation
  • Windows Audio Session API (WASAPI)

Networking

The following features are at least partially supported:

  • DHCP app
  • Windows Web Services

No alternatives: DHCP connectivity, EAP, HTTP server, NDF, RAS, SNMP

Security

The following features are at least partially supported:

  • Certificate enrollment
  • Credential management
  • Cryptography

No alternatives: Biometric API, Certificate validation

Storage

The following features are at least partially supported:

  • Directory create, delete, and enumerate
  • File mapping

No alternatives: IMAPI, Management (mount points, format, quotas), Oplocks, USN journal

System

The following features are at least partially supported:

  • Heap API, thread local storage (TLS)
  • Last error
  • Synchronization

No alternatives: console, current directory, fibers, named pipes, power

User interface

The following features are at least partially supported:

  • Direct Manipulation
  • National Language Support (NLS)
  • Strsafe functions
  • Text Services Framework (TSF)
  • Windows Animation Manager
  • UI automation

No alternatives: DDE/NetDDE, DWM, Magnifier, User: hooks, User: MDI, User: timers, User: shotdown,

.NET for Metro style apps

The .NET APIs for Metro style apps provide a set of managed types that you can use to create Metro style apps for Windows using C# or Visual Basic. The .NET APIs for Metro style apps include a subset of types from the .NET Framework.  You use these types with types from the Windows Runtime API to create Metro style apps.

In some cases, a type that you used in a .NET Framework application does not exist within the .NET APIs for Metro style apps; instead, you must use a type from the Windows Runtime. For example, the System.IO.IsolatedStorage.IsolatedStorageSettings class is not included in the .NET APIs for Metro style apps; instead, you use the Windows.Storage.ApplicationDataContainer class for app settings.

Converting existing .NET Framework code

Typically, you will not simply convert an existing .NET Framework application into a Metro style app. Building a Metro style app requires that you redesign the .NET Framework application for the new user experience. However, you may want to convert parts of an existing .NET Framework application for use in a new Metro style app.

UI changes

When you convert UI code from a Silverlight or Windows Phone application, you can use many of the same UI types, but the types are now located in the Windows.UI.Xaml namespaces instead of the System.Windows namespaces. These new UI types are similar to the previous .NET Framework UI types but contain some different members.

I/O changes

async

  • System.IO.Stream.BeginRead & EndRead –> System.IO.Stream.ReadAsync
  • System.IO.Stream.BeginWrite & EndWrite –> System.IO.Stream.WriteAsync
  • Close() –> Dispose() or using
  • System.IO.File.ReadAllText –> A method that uses the asynchronous I/O members
  • Code to retrieve and open a file

Storage changes

  • System.IO.IsolatedStorage.IsolatedStorageFile –> Windows.Storage.ApplicationData.Current.LocalFolder
  • System.IO.IsolatedStorage.IsolatedStorageSettings –> Windows.Storage.ApplicationData.Current.LocalSettings

Threading changes

  • System.Threading.Thread.MemoryBarrier –> System.Threading.InterLocked.MemoryBarrier
  • System.Threading.Thread.ManagedThreadId –> System.Threading.Environment.CurrentManagedThreadId
  • System.Threading.Thread.CurrentCulture –> System.Threading.CultureInfo.CurrentCulture
  • System.Threading.Thread.CurrentUICulture –> System.Threading.CultureInfo.CurrentUICulture
  • System.Threading.Timer –> Windows.System.Threading.ThreadPoolTimer
  • System.Threading.ThreadPool –> Windows.System.Threading.ThreadPool

You must change threading code to use the ThreadPool class in the Windows Runtime, or to use tasks with the asynchronous await feature.

Reflection changes

Most members from the System.Type class have been moved to the System.Reflection.TypeInfo class. You can retrieve the TypeInfo object by calling the System.Reflection.IntrospectionExtensions.GetTypeInfo(System.Type) method, which is an extension method for Type.

  • type.Assembly –> type.GetTypeInfo().Assembly
  • type.GetMethods(BindingFlags.DeclaredOnly) –> type.GetTypeInfo().DeclaredMethods
  • type.GetMethod("MethodName", BindingFlags.DeclaredOnly) –> type.GetTypeInfo().GetDeclaredMethod("MethodName")
  • type.GetNestedTypes() –> type.GetTypeInfo().DeclaredNestedTypes

Changes in general .NET Framework types

  • System.Environment.TickCount –> System.Diagnostics.Stopwatch.GetTimestamp
  • System.Net.WebClient –> System.Net.Http.HttpClient
  • System.IComparable –> System.IComparable<T>
  • System.ICloneable –> custom
  • System.Xml.XmlConvert.ToDateTime –> System.Xml.XmlConvert.ToDateTimeOffset
  • System.Array.AsReadOnly and System.Collections.Generic.List<T>.AsReadOnly –> new ReadOnlyCollection(list)

c.d.n

Brak komentarzy: