Deep Dive into WinRT - discover how the Windows Runtime is based on COM, how asynchronous operations work, how language projections enable access from a variety of languages, and what performance considerations are relevant for interoperability.
2. Introduction to Windows 8
COM Refreshment
Windows Runtime Objects and
API Broker Process
WinRT Types, Threading
Model, Asynchronous
Programming
Metadata, Language
Projections, and WinRT
Components
Interoperability with WinRT
Some slides taken from Microsoft
presentations, //build/ 2011
4. Full application compatibility with Windows 7
New immersive UI for slate form factors and
touch
New application framework for immersive apps
5. Windows 8
• “Standard” x86/x64 edition, including tablets
Windows 8 Pro
• Domain connectivity, encryption, Hyper-V
Windows 8 Enterprise
• Available only through volume licensing
Windows 8 RT [Windows on ARM]
• ARM only, mostly tablets, OEM installs
6. Windows 7 Developer Consumer
RTM Preview Preview
• September 2009 • //build, September • February 2012 Release
2011 RTM, GA
Candidate
7. Metro style Apps Desktop Apps
XAML HTML / CSS
JavaScript
C/C++ C#, VB HTML C C#
(Chakra) JavaScript C++ VB
Windows Runtime APIs
Communication Devices &
Graphics & Media
& Data Printing
Application Model Internet .NET
Explorer
Win32 SL
Windows Kernel Services
8. …are …are …can’t …loosely …can use a …are the
distributed subject to access coupled to restricted only ones
through strict sensitive other apps subset of to run on
the sandbox resources and the Windows Windows 8
Windows restrictions without system and .NET RT
Store permission APIs
s
9. Myth Reality
WinRT uses COM reference
WinRT objects are subject to
counting; managed Metro apps
garbage collection
use GC for managed objects
.NET Metro apps are compiled to .NET Metro apps use a subset of
native code and don’t require the .NET Framework and rely on
the CLR or the .NET Framework the CLR and JIT to run
There’s a separate CLR for .NET The desktop CLR and the Metro
Metro apps CLR are one and the same
11. App gets 5 seconds to App is not notified
handle suspend before termination
Apps are notified when
they have been resumed
12. Push Audio Background Background
notifications playback transfer tasks
Download files
Run in a separate
Update live tile from a remote
process
server
Play music in the
background
Triggered by
Create
Upload files to a time, push, netw
badges, multiple
remote server ork, system
tiles
events
13. AppContainer – Signed + Validated
Filtered to declared capabilities
in the package manifest
14. File access • Music, pictures, videos, documents, removable
capabilities storage
Device access • Webcam, microphone, location, SMS, proximity
capabilities
Network • Internet client, Internet client/server, private
capabilities network client/server
Private storage, simple sensors, settings, and much
more available without any declaration
16. • Packages are compressed and
signed, including manifest
Files / Assets
• Block map allows partial
downloads when you issue an
update AppXManifest.xml
BlockMap
Signature
Zip Central Directory
.appx package
17. • Windows App Certification Kit helps ensure you pass
Store certification steps
– UI application and command-line tool
• Certification steps:
Package Use of Launch and No crashes or
manifest supported suspend Security tests hangs during
compliance APIs only performance the run
20. • COM (Component Object Model) interfaces
is a binary standard for authoring
components
IUnknown
– Specifies how classes implement IStream
interfaces, how interfaces are
discovered, and how methods are
dispatched at runtime
• Most Windows languages can
consume and create COM objects
– C++, C#, VB6, Delphi, VBScript, …
21. • Coclasses and interfaces have IDs (GUIDs)
– Can also have human-readable ProgIDs
• COM objects are registered in the registry
– HKEY_CLASSES_ROOTCLSID, point to DLL location
• Metadata provided in type libraries (.tlb files)
• The COM binary exposes entry points for activation
– DllGetClassFactory IClassFactory
CreateInstance
– Activation can be in-process, out-of-process, or remote
(DCOM through port 135)
22. COM objects are reference-counted
Every operation that duplicates a reference must call AddRef
Every operation that removes a reference must call Release
IMyInterface* instance;
HRESULT hr = CoCreateInstance(CLSID_MyClass, NULL,
CLSCTX_INPROC_SERVER, IID_IMyInterface, (void**)&instance);
instance->AddRef(); COM Object
IMyInterface* anotherReference = instance;
instance->Release(); RC
anotherReference->Release();
23. COM objects can be consumed from .NET by using
their type library to generate an interop assembly
Or add a reference to a vendor-supplied PIA
tlbimp.exe ComLibrary.tlb /out:ComLibraryInterop.dll
Using COM objects is then very similar to managed
classes—new it up, and you’re good to go
Lifetime management is automatic, discussed later
ComLibrary.ComClass cc = new ComLibrary.ComClass();
cc.TransferFunds(“Joe”, “Mike”, 1400.0f);
24. • COM objects live in an
apartment STA
– A single-threaded apartment STA
(STA) has a single thread Thread Message
Queue
responsible for making all calls
COM Object
on its objects
– A multi-threaded apartment
(MTA) allows any thread to
make calls on its objects
• Data passed between
apartments is marshaled
28. • WinRT classes are registered in the registry
– The extensions catalog maps concrete WinRT classes to
contracts (launch, share, search, …)
– The class catalog describes WinRT classes
• Most WinRT objects are activated by name
– "MyComponent.MyNamespace.MyClass"
– Can work with activation factories (IActivationFactory)
to customize object construction
• Some WinRT objects are activated by contract
– “Share operation required for data of type image/png”
29. Extension Catalog Class Catalog
Extension 1 Runtime Class “A”
Launch
Contract
Extension 2 Runtime Class “B”
Search
Extension 3 Runtime Class “C”
Contract
30. RoActivateInstance creates a raw WinRT
component by name
The code below omits IUnknown::Release calls
HSTRING className;
LPCWSTR pszClassName = L"MyComponent.MyNamespace.MyClass";
IInspectable* instance;
IMyInterface* interface;
HRESULT hr;
hr = WindowsCreateString(pszClassName, wcslen(pszClassName), &className);
hr = RoActivateInstance(className, &instance);
WindowsDeleteString(className);
hr = instance->QueryInterface(IID_IMyInterface, (void**)&interface);
31. Language
Wrapper bound to
projection creates
RoActivateInstance object and
a wrapper using
returned to app
metadata
Object created
Catalog finds and
internally, returns
loads the DLL
IInspectable
DllGetActivation Factory->
Factory ActivateInstance()
32. • WinRT object reference = pointer to a pointer to a
vtable, which is an array of pointers to functions
– IUnknown methods first, then IInspectable methods
– Metadata, discussed next, aids in on-the-fly discovery
• Parameters are passed using the stdcall convention
33. IInspectable* instance = ...;
typedef HRESULT (__stdcall *MatrixMultiply)(
void* pThis, int* A, int m, int w,
int* B, int n, int* C);
MatrixMultiply pfn = (MatrixMultiply)((void**)*((void**)instance))[6];
int* A = new int[1048576];
int* B = new int[1048576];
int* C = new int[1048576];
pfn(instance, A, 1024, 1024, B, 1024, C);
35. WinRT Type [Partial] .NET Equivalent
Boolean Boolean
Byte Byte Note
DateTime DateTimeOffset • The object model
is very similar
Guid Guid • Reference types
(classes, derived
Int64 Long from Object)
and value types
Object Object
String String
TimeSpan TimeSpan
36. WinRT Interface .NET Projection
IMap<K,V> IDictionary<K,V>
IMapView<K,V> IReadOnlyDictionary<K,V> Tip
IVector<T> IList<T> • You shouldn’t use
the original WinRT
IVectorView<T> IReadOnlyList<T> interfaces in .NET
code—use only
the projections
IIterable<T> IEnumerable<T>
IIterator<T> IEnumerator<T>
IBindableVector IList
IBindableIterable IEnumerable
37. • Most WinRT objects are MTA, except GUI objects
– Some objects are hosted out-of-process (brokered)
RuntimeBroker.exe
App
Projection
Proxy
Windows
Runtime Object
38. Synchronous: Wait for result, then continue
Asynchronous: Post callback, do something else
NOTE: Parallel/concurrent does not mean asynchronous:
Parallel.For is blocking, from its caller’s perspective!
string data = ObtainDataFromServer(uri);
DisplayData(data);
ObtainDataFromServer(uri, data => DisplayData(data));
Task.Factory.StartNew(() => ObtainDataFromServer())
.ContinueWith(t => DisplayData(t.Result));
39. • User interaction—do asynchronous work, the UI
remains responsive
– Challenge: marshal the continuation (callback) back to the UI
thread, due to UI controls’ thread affinity
• Scalability—some threads are scarce, some aren’t
– Reuse thread for other requests while the work is in progress
– Can differentiate CPU and I/O threads
40. • All APIs that can take longer than 50ms are
asynchronous
– No synchronous (blocking) versions
– In many cases, asynchrony improves scalability
• APIs return IAsync... interfaces
– IAsyncAction, IAsyncActionWithProgress<TProgress>
– IAsyncOperation<TResult>, IAsyncOperationWithProgress<T
Result,TProgress>
41. Working with the async APIs directly is cumbersome
We will see better alternatives later
Geolocator locator = new Geolocator();
IAsyncOperation<Geoposition> asyncOp = locator.GetGeopositionAsync();
asyncOp.Completed = new AsyncOperationCompletedHandler<Geoposition>(
(aop, status) =>
{
MessageDialog message = new MessageDialog("Location retrieved");
message.ShowAsync();
}
);
43. • WinRT components ship
metadata in .winmd files
– ECMA-335 format, same as .NET
assemblies
– Windows metadata in
Windows.winmd
– Enable various languages to
bind to the object, support
IntelliSense
– How to bind is up to the
language—COM defines the ABI
44. • WinRT components are DLLs accompanied by .winmd
files that contain WinRT classes
• Cannot be distributed through the store stand-alone
• Cannot be shared between applications
• Can be sold through traditional software licensing
– UI control frameworks, graphics libraries, math, etc.
45. • WinRT component = class library
– Compile to generate a .winmd file (metadata)
• There are some limitations on what can be exported
– Only sealed classes are allowed
– Only WinRT types can be passed across the interop boundary
– Take care of passing collections around
Can use the resulting library from JavaScript, C++, or C#
Metro-style apps
46. “WinRT Component DLL” project type
Use C++/CX extensions to export types
Can use the resulting library from JavaScript, C#, or C++
Metro-style apps
public ref class WinRTComponent sealed {
public:
WinRTComponent() {}
Platform::String^ GetString(int number) {
return number.ToString();
}
};
48. C++ App
Projection
C#/VB App
Projection
CLR
Object HTML App
Projection
Windows Metadata Chakra
49. All WinRT APIs are projected automatically to all
languages: C#, C++, JavaScript
Projections behave according to the target language’s rules
Geolocator locator = new Geolocator();
Geoposition pos = await locator.GetGeopositionAsync();
MessageDialog dialog = new MessageDialog(pos.CivicAddress.ToString());
dialog.ShowAsync();
document.querySelector("#locationButton").onclick = function () {
var locator = new Windows.Devices.Geolocation.Geolocator();
locator.getGeopositionAsync().then(function (pos) {
resultText.textContent = pos.civicAddress;
});
};
50. • WinRT asynchronous operations are projected to first-
class concurrency libraries in C#, C++, JavaScript
– Can be awaited in C#
– Can be converted to concurrency::task in C++
– Act like a promise in JavaScript
• Similarly, language concurrency libraries can produce
WinRT asynchronous operations
51. async void buttonUpdate_Click() {
status.Text = "Downloading updates..."; runs on UI thread
int count = await GetUpdatesAsync(clientID); returns immediately
status.Text = "Got " + count + "updates"; callback, runs on UI thread
}
Task<int> GetUpdatesAsync(string clientID) {
return Task.Run(() => GetUpdates(clientID)); runs on ThreadPool thread
}
async void buttonDownload_Click() { //downloads are parallel!
Task<byte[]> first = DownloadPartAsync(1);
Task<byte[]> second = DownloadPartAsync(2);
DisplayTwoParts(await first, await second);
}
52. Async methods can use arbitrary control flow
The C# 5 compiler translates everything
Example: Cancellation
async DownloadLargeFile(string url) {
_cts = new CancellationTokenSource();
try {
byte[] result = await DownloadFileAsync(url, cts.Token);
PlayMovie(result);
} catch (OperationCanceledException) {
UpdateStatus("Download canceled.");
}
}
void CancelDownload() { _cts.Cancel(); }
53. WindowsRuntimeSystemExtensions contains
extension methods for asynchronous operations
Supports GetAwaiter() for await pattern!
CameraCaptureUI capture = new CameraCaptureUI();
capture.PhotoSettings.MaxResolution =
CameraCaptureUIMaxPhotoResolution.MediumXga;
var result = await capture.CaptureFileAsync(CameraCaptureUIMode.Photo);
//Compiled to:
WindowsRuntimeSystemExtensions.GetAwaiter<StorageFile>(
capture.CaptureFileAsync(CameraCaptureUIMode.Photo));
...
54. WindowsRuntimeSystemExtensions contains
extension methods for asynchronous operations
Can produce WinRT async operations!
public sealed class HttpRetriever {
public IAsyncOperation<string> GetUrl(string uri) {
return Task.Run(async () =>
{
HttpClient httpClient = new HttpClient();
string result = await httpClient.GetStringAsync(uri);
return result;
}).AsAsyncOperation();
}
}
55. ConcRT’s task class can wrap a WinRT async operation
and create a continuation chain
Somewhat similar to C#’s await, only manual
CameraCaptureUI^ capture = ref new CameraCaptureUI();
task<StorageFile^> captureTask(
capture->CaptureFileAsync(CameraCaptureUIMode::Photo));
captureTask.then([] (StorageFile^ result) {
MessageDialog^ dialog = ref new MessageDialog(result->Name);
dialog->ShowAsync();
});
56. ConcRT ships with a create_async function that
generates a WinRT async operation implementation
Progress reporting and cancellation also supported
IAsyncOperationWithProgress<int,int>^ Math::CountPrimes(
int start, int end)
{
return create_async([=](progress_reporter<int> progress) {
int count = 0;
for (int i = start; i < end; ++i) {
if (IsPrime(i)) ++count;
if (i % 100 == 0) progress.report(i);
}
return count;
});
}
57. WinRT async operations are converted to promises in
JavaScript, which offer .then() for continuations
var retriever = new ManagedComponent.HttpRetriever();
retriever.getUrl("http://blog.sashag.net/").then(
function (result) {
...
},
function (error) {
...
}
);
60. • Interop mainly has to deal with object lifetime
inconsistency
– COM implements reference counting
– .NET uses a tracing GC
• RCW = Runtime Callable Wrapper
– References a COM object, +1 to the RC
– Implements a finalizer that decrements the RC
– Marshal.ReleaseComObject is the Dispose equivalent
• CCW = COM Callable Wrapper
– References a managed object as a COM interface
61. • Reference cycles between RCWs and CCWs may
cause memory leaks
Managed
Object
The GC can’t see
CCW RCW below this line
COM
Object
62. The biggest performance problems are chatty
interfaces and data copies
Most data copies can be eliminated by careful API design
(e.g. accept a buffer for filling instead of returning it)
Design chunky interfaces
//Chatty interface:
void SetElement(int index, int value);
//Chunky interface:
void SetElementRange(int begin, int end, int[] values);
64. • The Visual Studio Profiler partially supports Metro
applications in full—managed, native, and JavaScript
– VSPerf.exe tool can do command-line profiling, too
Sampling Instrumentation Allocations Concurrency
• CPU-bound apps, very • I/O-bound apps, CPU- • Details on who • Only desktop apps
low overhead bound apps, higher allocated and what
• Full program stacks overhead • Only managed code
(including all system • More detailed timing • Only desktop apps
DLLs) data, limited stacks
• Tier interactions • Only JavaScript apps
65.
66. Introduction to Windows 8
COM Refreshment
Windows Runtime Objects and API
Broker Process
WinRT Types, Threading
Model, Asynchronous Programming
Metadata, Language
Projections, and WinRT Components
Interoperability with WinRT
Explain that the relationship between Metro and desktop applications is tense—Metro apps have only very limited interaction options with desktop applications, and are not allowed (by Store guidelines) to assume that a desktop counterpart exists…
Mention that a small number of WinRT APIs can be accessed from desktop applications, e.g. toast notifications.
Certification requirements:http://msdn.microsoft.com/en-us/library/windows/apps/hh694083.aspxTechnical details about the kit:http://msdn.microsoft.com/en-us/library/windows/apps/hh694081.aspxhttp://msdn.microsoft.com/en-us/library/windows/apps/hh750314.aspx
Launch the kit from C:\\Program Files\\Windows Kits\\8.0\\App Certification Kit\\appcertui.exe and let it certify some application. This takes a while :-)Show ready-made result: StoreCertificationResult.xml
Extension catalog – HKCU\\Software\\Classes\\Extensions\\ContractIdClass catalog – HKCU\\Software\\Classes\\ActivatableClasses\\Package: show all parts including Server part for application with ExePath, and component part with DllPathGood reference: http://www.codeproject.com/Articles/339900/Under-the-hood-Part-3-Internals-of-how-the-applica
Don’t show how to consume directly from languages—this is discussed in the next section under the rest of the projections.