Georg fährt extra nach Berlin um Steve Ballmer zu treffen

8 Tage Windows Phone 8 | Tag #5: .NET 4.5 und C# 5.0

Die­ser Arti­kel ist Tag #5 der Serie 8 Tage Win­dows Pho­ne 8 von Geert van der Cru­ij­sen.

Der Ori­gi­nal­ar­ti­kel befin­det sich hier: 8 days of Win­dows Pho­ne 8 — Day 5: .net 4.5 & C# 5.0.

8 Tage Windows Phone 8

Will­kom­men zurück zu mei­ner Arti­kel­se­rie 8 Tage Win­dows Pho­ne 8. Heu­te, am fünf­ten Tag der Serie, reden wir über die neu­en Fea­tures im .NET 4.5 Frame­work und in der Spra­che C# 5.0. Die­se kön­nen Ihnen dabei hel­fen, tol­le Win­dows Pho­ne Anwen­dun­gen zu bau­en. Die Fea­tures, auf die wir heu­te beson­ders ein­ge­hen wol­len, sind die Schlüs­sel­wör­ter async und await und der Dat­a­Con­trac­t­J­son­Se­ria­li­zer.

day5

.NET Framework 4.5 und C# 5.0

Bei der Aktua­li­sie­rung einer Anwen­dung von Win­dows Pho­ne 7 auf Win­dows Pho­ne 8 aktua­li­sie­ren wir die­se auch von Sil­ver­light auf das .NET 4.5 Frame­work und die C# 5.0 Spra­che. Damit bekom­men Win­dows Pho­ne Ent­wick­ler eini­ge neue Fea­tures, die nicht wirk­lich Teil des SDK sind, die aber extrem nütz­lich für Sie als Ent­wick­ler von mobi­len Anwen­dun­gen sind. Eines die­ser neu­en Fea­tures ist das async und await Mus­ter. Damit wird das Bau­en von asyn­chro­nen Anwen­dun­gen wesent­lich ver­ein­facht und trägt damit indi­rekt zu einer reak­ti­ven Benut­zer­schnitt­stel­le für den End­nut­zer bei. Das ande­re The­ma, auf das ich heu­te ein­ge­hen möch­te, ist die Ver­wen­dung des Dat­a­Con­trac­t­J­son­Se­ria­li­zer. Die­se Klas­se hilft Ihnen, zwi­schen Objek­ten und JSON Strings zu seria­li­sie­ren und zu dese­ria­li­sie­ren. Das ist sehr nütz­lich, wenn man aus einer App auf Diens­te im Web zugreift.

Unglück­li­cher­wei­se ver­wen­den (noch?) nicht alle APIs im SDK die async und await Schlüs­sel­wör­ter. Web­Cli­ent und HttpWeb­Re­quest ver­wen­den die­ses Fea­ture nicht. Mög­li­cher­wei­se wer­den wir irgend­wann den HttpCli­ent wie unter Win­dows 8 ver­wen­den kön­nen.

In der Bei­spiel­an­wen­dung zum heu­ti­gen Arti­kel woll­te ich idea­ler­wei­se die Demons­tra­ti­on des asyn­c/a­wait-Pat­terns und des JSON Seria­li­zers kom­bi­nie­ren. Da wir das asyn­c/a­wait-Pat­tern nicht ver­wen­den kön­nen, um eine Datei aus dem Web zu holen, laden wir ein­fach eine loka­le Datei. Die APIs zum Zugriff auf loka­le Datei­en ver­wen­den die Klas­se Task und damit das asyn­c/a­wait-Pat­tern. Fan­gen wir also an, eine sehr ein­fa­che TODO-Lis­ten-Anwen­dung zu bau­en.

Erstel­len Sie ein neu­es Win­dows Pho­ne 8 Pro­jekt und fügen Sie eine Klas­se ToDo hin­zu. Die­se wer­den wir zur Beschrei­bung eines Ein­trags in der TODO-Lis­te ver­wen­den. Um die­se Daten spä­ter in einer JSON Datei spei­chern zu kön­nen, fügen wir eini­ge Attri­bu­te hin­zu, damit der Dat­a­Con­trac­t­J­son­Se­ria­li­zer weiß, wie die Daten in eine JSON Datei seria­li­siert wer­den sol­len. Fügen Sie das [Dat­a­Con­tract] Attri­but der ToDo Klas­se hin­zu und das [Data­Mem­ber] Attri­but allen Eigen­schaf­ten, die nach JSON seria­li­siert wer­den sol­len. Stan­dard­mä­ßig wird der Seria­li­zer den Ele­men­ten in der JSON Datei die sel­ben Namen geben wie die ent­spre­chen­den Eigen­schaf­ten in Ihrer Klas­se. Wenn Sie möch­ten, dass die Ele­men­te in der JSON Datei einen ande­ren Namen haben, kön­nen Sie das Data­Mem­ber Attri­but ent­spre­chend ver­än­dern. Im Code unten sehen Sie dies am Bei­spiel der Eigen­schaft Con­tent. Das ent­spre­chen­de Feld in der JSON Datei wird den Namen „Text“ haben.

[DataContract]
public class ToDo
{   
   [DataMember]
   public string Title { get; set; }
 
   [DataMember]
   public DateTime Date { get; set; }

   [DataMember(Name="Text")]
   public string Content { get; set; }
 }

Nach­dem wir jetzt einen ein­fa­chen Con­tai­ner für unse­re Objek­te haben, las­sen Sie uns etwas Geschäfts­lo­gik mit dem Namen ToDo­Ser­vice erstel­len, um die Lis­te der Auf­ga­ben zu spei­chern und wie­der aus der Datei in einem loka­len Ord­ner (LocalF­ol­der) zu laden. LocalF­ol­der ist der Wur­zel­ord­ner Ihrer Anwen­dungs­da­ten — unter Win­dows Pho­ne 7 war das Iso­la­ted Sto­rage.

Als ers­tes fügen wir unse­rem ToDo­Ser­vice eine Metho­de hin­zu, um die Lis­te der Auf­ga­ben zu spei­chern.

public async Task<string> SaveToDos()
{
   List<ToDo> todos = new List<ToDo>();

   todos.Add(new ToDo(){Title="todo 1", Date = DateTime.Now, Content="finish this series of blogposts"});
   todos.Add(new ToDo(){Title="todo 2", Date = DateTime.Now, Content="Pick up milk from the store"});
   todos.Add(new ToDo(){Title="todo 3", Date = DateTime.Now, Content="Wash my car"});

   var localFolder = Windows.Storage.ApplicationData.Current.LocalFolder;

   DataContractJsonSerializer dcjs = new DataContractJsonSerializer(typeof(List<ToDo>));
   MemoryStream ms = new MemoryStream();
   dcjs.WriteObject(ms,todos);

   string json = Encoding.UTF8.GetString(ms.ToArray(),0,(int)ms.Length);

   StorageFile todoFile = await localFolder.CreateFileAsync("todos.json",CreationCollisionOption.ReplaceExisting);

   using (var f = await todoFile.OpenStreamForWriteAsync())
   {
      await f.WriteAsync(ms.ToArray(),0,(int)ms.Length);
      f.Close();
   }

   return json; 
}

Beach­ten Sie das async Schlüs­sel­wort vor dem Rück­ga­be­typ in der Metho­de. Damit kann die Metho­de asyn­chron auf­ge­ru­fen wer­den und sie wird immer einen Task zurück­ge­ben, wel­cher den Rück­ga­be­wert beinhal­tet. In der Metho­de fül­len wir die Lis­te der Auf­ga­ben zunächst mit eini­gen Ein­trä­gen. Danach erstel­len wir einen Dat­a­Con­trac­t­J­son­Se­ria­li­zer. Dabei geben wir im Kon­struk­tor an, wel­chen Typ wir seria­li­sie­ren wol­len. Wir ver­wen­den dann den Dat­a­Con­trac­t­J­son­Se­ria­li­zer, um die Lis­te der Auf­ga­ben in eine JSON Zei­chen­ket­te zu seria­li­sie­ren. Die­sen geben wir am Ende der Metho­de zurück.

Sobald wir den JSON String haben, erstel­len wir eine neue Datei im loka­len Ord­ner, indem wir die Metho­de Crea­teFi­leA­sync auf­ru­fen. Beach­ten Sie das await Schüs­sel­wort im Auf­ruf der Metho­de, wel­cher grob bedeu­tet, dass der Code unter­halb des Auf­rufs erst aus­ge­führt wird, wenn der asyn­chro­ne Auf­ruf abge­schlos­sen ist. Wenn die loka­le Datei erstellt ist, schrei­ben wir ein­fach die JSON Zei­chen­ket­te in die­se Datei und schlie­ßen den Stream.

Jetzt, wo wir die Auf­ga­ben­lis­te in die loka­le Datei gespei­chert haben, las­sen Sie uns die­se wie­der lesen und am Bild­schirm anzei­gen. Wir imple­men­tie­ren hier­zu in unse­rem ToDo­Ser­vice eine wei­te­re Metho­de mit dem Namen Get­To­Dos(). Die­se liest die JSON Datei ein und dese­ria­li­siert die­se zurück in die Lis­te der Auf­ga­ben.

public async Task<List<ToDo>> GetToDos()
{
   var localFolder = Windows.Storage.ApplicationData.Current.LocalFolder;

   StorageFile todoFile = await localFolder.GetFileAsync("todos.json");
   DataContractJsonSerializer dcjs = new DataContractJsonSerializer(typeof(List<ToDo>));

   var stream = await todoFile.OpenStreamForReadAsync();
   var todos = dcjs.ReadObject(stream) as List<ToDo>;

   return todos;
}

Wir begin­nen wie­der, indem wir uns eine Refe­renz auf den loka­len Ord­ner und auf die JSON Datei holen. Nach­dem wir das Sto­rage­Fi­le Objekt haben, erstel­len wir wie­der einen neu­en Dat­a­Con­trac­t­J­son­Se­ria­li­zer. Wir öff­nen den Stream aus unse­rer Sto­rage­Fi­le und über­ge­ben die­sen an den Dat­a­Con­trac­t­J­son­Se­ria­li­zer, um die Daten zurück in eine Lis­te von Auf­ga­ben zu dese­ria­li­sie­ren. Damit sind wir fer­tig.

Um die Demo abzu­schlie­ßen, fügen wir der Haupt­sei­te eine Text­Box hin­zu, in wel­cher wir die JSON Zei­chen­ket­te dar­stel­len. Wei­ter­hin bau­en wir ein ItemsCon­trol ein, wel­ches die Lis­te der Auf­ga­ben anzeigt.

<StackPanel x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
   <ScrollViewer>
      <StackPanel>
         <TextBlock x:Name="JsonText" TextWrapping="Wrap" Style="{StaticResource PhoneTextNormalStyle}"></TextBlock>
         <ItemsControl x:Name="TodoList" ItemTemplate="{StaticResource TodoItemTemplate}" Margin="0,12,0,0"></ItemsControl>
      </StackPanel>
   </ScrollViewer>
</StackPanel>

In der Code Behind Datei fügen wir nun alles zusam­men, um die Daten zu schrei­ben, zu lesen und anzu­zei­gen.

public async void SaveAndGetTodos()
{
   ToDoService ts = new ToDoService();
   string json = await ts.SaveToDos();
   List<ToDo> todos = await ts.GetToDos();
   JsonText.Text = json;
   TodoList.ItemsSource = todos;
}

Wenn wir unse­re Demo­an­wen­dung jetzt lau­fen las­sen, sehen wir den JSON String, wel­cher durch den Dat­a­Con­trac­t­J­son­Se­ria­li­zer erstellt wur­de und außer­dem die Lis­te der Auf­ga­ben im ItemsCon­trol.

day5demo

Sie kön­nen das Bei­spiel­pro­jekt hier her­un­ter­la­den: http://sdrv.ms/QSJ2yx.

Hof­fent­lich hat Ihnen das Lesen die­ses Arti­kels Spaß gemacht und Sie haben etwas über async/await und den Dat­a­Con­trac­t­J­son­Se­ria­li­zer gelernt. Mor­gen gibt’s mehr über eines der cools­ten Fea­tures im neu­en SDK: die APIs zur Sprach­steue­rung.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert