Back to the future: sockets and relational data in your (Windows) - - PowerPoint PPT Presentation

back to the future sockets and relational data in your
SMART_READER_LITE
LIVE PREVIEW

Back to the future: sockets and relational data in your (Windows) - - PowerPoint PPT Presentation

Back to the future: sockets and relational data in your (Windows) pocket Dragos Manolescu Microsoft, Windows Phone Engineering Hewlett-Packard Cloud Services Background APIs Performance and Health Data and Cloud RTM Networking:


slide-1
SLIDE 1

Dragos Manolescu Microsoft, Windows Phone Engineering

Back to the future: sockets and relational data in your (Windows) pocket

Hewlett-Packard Cloud Services

slide-2
SLIDE 2

Background

APIs Performance and Health Data and Cloud

slide-3
SLIDE 3

RTM Networking: WebClient and XmlHttpRequest Persistent data: Isolated storage

slide-4
SLIDE 4

Phone application development is different:

  • design
  • horsepower
  • IO
  • battery
slide-5
SLIDE 5

Power Usage Profiles

12.5 25 37.5 50 Laptop Phone

Typical use between charges (h) Battery size (Ah)

slide-6
SLIDE 6

Touch sensor

Current Power

10s of mW

slide-7
SLIDE 7

HTTP request/response

Current Power

1000 of mW

slide-8
SLIDE 8

DCVS example

  • CPU at 100%
  • Modulate f and V
  • Avoid spreading work
slide-9
SLIDE 9

New in Mango (subset)

  • Multitasking
  • Fast application switching
  • Background agents
  • Sensor fusion
  • Sockets
  • Network information
  • Device status
  • Local database
  • Contacts & calendar
slide-10
SLIDE 10

Sockets

  • Instant messaging
  • Multi-player games
  • Streaming
slide-11
SLIDE 11

TCP

slide-12
SLIDE 12

TCP Connect

var result = string.Empty; var hostEntry = new DnsEndPoint("www.bing.com", 80); _socket = new Socket( AddressFamily.InterNetwork , SocketType.Stream , ProtocolType.Tcp); var socketEventArg = new SocketAsyncEventArgs { RemoteEndPoint = hostEntry }; socketEventArg.Completed += (s, e) => { result = e.SocketError.ToString(); }; _socket.ConnectAsync(socketEventArg);

slide-13
SLIDE 13

Warning!

Power measurements performed on engineering devices

slide-14
SLIDE 14

Average power: 930mW

Current Power

slide-15
SLIDE 15

TCP Send

var response = "Operation Timeout"; var socketEventArg = new SocketAsyncEventArgs { RemoteEndPoint = _socket.RemoteEndPoint , UserToken = null }; socketEventArg.Completed += (s, e) => { response = e.SocketError.ToString(); _clientDone.Set(); }; var payload = Encoding.UTF8.GetBytes(data); socketEventArg.SetBuffer(payload, 0, payload.Length); _socket.SendAsync(socketEventArg);

slide-16
SLIDE 16

Average power: 1400mW

Current Power

slide-17
SLIDE 17

TCP Receive

var response = "Operation Timeout"; var socketEventArg = new SocketAsyncEventArgs {RemoteEndPoint = _socket.RemoteEndPoint}; socketEventArg.SetBuffer(new Byte[MAX_BUFFER_SIZE], 0, MAX_BUFFER_SIZE); socketEventArg.Completed += (s, e) => { if (e.SocketError == SocketError.Success) response = Encoding.UTF8.GetString (e.Buffer,e.Offset,e.BytesTransferred); else response = e.SocketError.ToString(); _clientDone.Set(); }; _clientDone.Reset(); _socket.ReceiveAsync(socketEventArg); _clientDone.WaitOne(TIMEOUT_MILLISECONDS); return response;

More elegant solution with .NET 4 Task and await:

async Task<Byte[]> Receive() { // ... return await ReceiveAsync(); }

slide-18
SLIDE 18

Average power: 830mW

Current Power

slide-19
SLIDE 19

UDP

slide-20
SLIDE 20

UDP Join Multicast Group

var groupAddress = IPAddress.Parse("224.0.1.1"); _client = new UdpAnySourceMulticastClient ( groupAddress , 8900); _client.BeginJoinGroup( result => { _client.EndJoinGroup(result); _client.MulticastLoopback = true; Send("Joined the group"); // ready to receive }, null);

WiFi Only

slide-21
SLIDE 21

UDP Send/Receive

// Send _client.BeginSendToGroup(data, 0, data.Length, result => _client.EndSendToGroup(result), null); // Receive _client.BeginReceiveFromGroup(recBuffer, 0, recBuffer.Length, result => { _client.EndReceiveFromGroup(result, out source); string dataReceived = Encoding.UTF8.GetString (_receiveBuffer, 0, _receiveBuffer.Length); Receive(); // next message from the group }, null);

WiFi Only

slide-22
SLIDE 22

Network Preferences

slide-23
SLIDE 23

Connect to specific interface

sock = new Socket( AddressFamily.InterNetwork , SocketType.Stream , ProtocolType.Tcp); var netList = new NetworkInterfaceList(); foreach (NetworkInterfaceInfo info in netList) { if (info.InterfaceType == NetworkInterfaceType.Wireless80211) { sock.AssociateToNetworkInterface(info); // extension break; } }

slide-24
SLIDE 24

Query interface

private void SocketEventArg_Completed(object sender, SocketAsyncEventArgs args) { if (args.LastOperation == SocketAsyncOperation.Connect && args.SocketError == SocketError.Success) { var ifName = sock.GetCurrentNetworkInterface() // extension .InterfaceName; } } // similar for WebRequest

slide-25
SLIDE 25

Network change notification

DeviceNetworkInformation.NetworkAvailabilityChanged += (src, networkArgs) => { /* name, bandwidth, characteristics */ NetworkInterfaceInfo nInterface = networkArgs.NetworkInterface; /* characteristic update (roaming, type, bandwidth), connected, disconnected */ NetworkNotificationType nType = networkArgs.NotificationType; };

slide-26
SLIDE 26

Name resolution

var endpoint = new DnsEndPoint("www.bing.com", 80, AddressFamily.InterNetwork); var nrResult = new NameResolutionResult(); var ninterface = default(NetworkInterfaceInfo); DeviceNetworkInformation.ResolveHostNameAsync(endpoint, ninterface, /* resolve on this interface */ (NameResolutionResult result) => { nrResult = result; _waitEventHandle.Set(); }, null); _waitEventHandle.WaitOne(); var ipEndPoints = from ipEndPoint in nrResult.IPEndPoints where ipEndPoint.AddressFamily == AddressFamily.InterNetwork select ipEndPoint;

slide-27
SLIDE 27

Net preference/requirement

SetNetworkPreference(this Socket socket, NetworkSelectionCharacteristics preference) SetNetworkRequirement(this Socket socket, NetworkSelectionCharacteristics requirement) NetworkInterfaceInfo GetCurrentNetworkInterface(this Socket socket) SetNetworkPreference(this WebRequest request, NetworkSelectionCharacteristics preference) SetNetworkRequirement(this WebRequest request, NetworkSelectionCharacteristics requirement) NetworkInterfaceInfo GetCurrentNetworkInterface(this WebRequest request) NetworkSelectionCharacteristics: Cellular, NonCellular

slide-28
SLIDE 28

Developer Notes

  • Old and new code (UDP SendTo, ReceiveFrom)
  • Two async models (completed event, IAsyncResult)
  • Phone integration points:
  • Connection manager
  • Fast application switching
  • Background services
  • Network preferences: interface state, type,

subtype, characteristics

slide-29
SLIDE 29

Local Storage

slide-30
SLIDE 30

Database

  • Offline data cache
  • Reference data
  • Search/sort quickly
  • Application state
  • Schema changes for application updates
slide-31
SLIDE 31

LINQ-to-SQL API

  • DataContext: entry point for
  • Database management
  • Composing queries
  • Issuing changes
  • Mapping Attributes:
  • Classes and members <-> tables and columns
  • MetaModel for change processor
  • ITable, ITable<T>: IQueryable and IQueryProvider
slide-32
SLIDE 32

Data Context

public class ToDoDataContext : DataContext { public ToDoDataContext(string connStr) : base(connStr) { } public Table<ToDoItem> Items; public Table<ToDoCategory> Categories; } using (ToDoDataContext db = new ToDoDataContext("isostore:/ToDo.sdf")) { if (db.DatabaseExists() == false) { db.CreateDatabase(); } }

Code-first

slide-33
SLIDE 33

Mapping

[Table] public class ToDoItem : INotifyPropertyChanged, INotifyPropertyChanging { [Column(IsPrimaryKey = true, IsDbGenerated = true, DbType = "INT NOT NULL Identity", CanBeNull = false, AutoSync = AutoSync.OnInsert)] public int ToDoItemId { /* … */ } [Column] public string ItemName { /* … */ } [Column] public bool IsComplete { /* … */ } // Version column aids update performance. [Column(IsVersion = true)] private Binary _version; // Association between this key and that "storage" table [Association(Storage = "_category", ThisKey = "_categoryId", OtherKey = "Id", IsForeignKey = true)] public ToDoCategory Category { /* … */ } }

slide-34
SLIDE 34

Insert

var newToDoItem = new ToDoItem { /* ... */ }; toDoDB.Items.InsertOnSubmit(newToDoItem); toDoDB.SubmitChanges();

slide-35
SLIDE 35

Average Power ≈ 500mW

Current Power

slide-36
SLIDE 36

Query

var toDos = from ToDoItem todo in toDoDB.Items where todo.IsComplete select todo;

slide-37
SLIDE 37

Average Power ≈ 500mW

Current Power

slide-38
SLIDE 38

Update

var updateItem = (from ToDoItem todo in toDoDB.Items where todo.ToDoItemId == 42 select todo) .First(); updateItem.IsComplete = false; toDoDB.SubmitChanges();

slide-39
SLIDE 39

Average Power ≈ 500mW

Current Power

slide-40
SLIDE 40

Delete

toDoDB.Items.DeleteOnSubmit(toDoForDelete); toDoDB.SubmitChanges();

slide-41
SLIDE 41

Average Power ≈ 500mW

Current Power

slide-42
SLIDE 42

Other Local Data

slide-43
SLIDE 43

Contacts data sources

Provider Name Picture Other Appts WP ✔ ✔ ✔ ✔ WL Social ✔ ✔ ✔ ✔ WL Rolodex ✔ ✔ ✔ ✔ Exchange ✔ ✔ ✔ ✔ MO ✔ ✔ ✔ ✘ facebook ✔ ✔ ✘ ✘ WL Agg ✘ ✘ ✘ ✘

WL = Windows Live

slide-44
SLIDE 44

Contacts

var cons = new Contacts(); cons.SearchCompleted += (s, scea) => { ContactResultsData.DataContext = scea.Results; var textBlock = (TextBlock) scea.State; ContactResultsLabel.Text = ContactResultsData.Items.Count > 0 ? "results (tap name for details...)" : "no results"; }; cons.SearchAsync( "google" , FilterKind.EmailAddress , ContactResultsLabel );

Read-only access Built-in filters are pre- indexed LINQ possible; bypass filters

slide-45
SLIDE 45

Average Power ≈ 500mW

Current Power

slide-46
SLIDE 46

Contacts with LINQ

Contacts cons = new Contacts(); cons.SearchCompleted += (s, e) => { ContactResultsDataLINQ.DataContext = from Contact con in e.Results from ContactEmailAddress a in con.EmailAddresses where a.EmailAddress.Contains("google") select con; }; cons.SearchAsync(String.Empty, FilterKind.None, null);

slide-47
SLIDE 47

Average Power ≈ 500mW

Current Power

slide-48
SLIDE 48

Appointments

var appts = new Appointments(); appts.SearchCompleted += (s, asea) => { StartDate.Text = asea.StartTimeInclusive.ToShortDateString(); EndDate.Text = asea.EndTimeInclusive.ToShortDateString(); AppointmentResultsData.DataContext = asea.Results; var textBlock = (TextBlock) asea.State; textBlock.Text = AppointmentResultsData.Items.Count > 0 ? "results (tap for details...)" : "no results"; }; var start = DateTime.Now; var end = start.AddDays(7); appts.SearchAsync(start, end, 20, AppointmentResultsLabel);

slide-49
SLIDE 49

Average Power: ≈500mW

Current Power

slide-50
SLIDE 50

Developer Notes

  • ExecuteCommand: not supported
  • ADO.NET Objects (such as DataReader): not supported
  • Only SQL CE data types are supported
  • Data binding:
  • Table.IListSource.GetList Method is not supported
  • BinaryFormatter is not supported
  • Take() requires a constant argument in LINQ queries
  • Skip() and Take() require an ordered list
  • Built-in searches vs LINQ
slide-51
SLIDE 51

Summary

slide-52
SLIDE 52
  • New features:
  • TCP and UDP sockets
  • Network Preferences
  • Local storage
  • Power profiles
  • Idiosyncrasies and developer notes
slide-53
SLIDE 53
  • SDK download: http://j.mp/paVn3s
  • Mango new features: http://j.mp/nrMGRj
  • .NET4 Task<T>: http://j.mp/pf5yJq
  • Local db best practices: http://j.mp/qviI4F

Next Steps

slide-54
SLIDE 54

Thank you!

@hysteresis