2016-08-21 4 views
1

Ich habe versucht, die Geschwindigkeit von ModernHttpClient zu testen, als ich Folgendes festgestellt: das Etikett ist nicht aktualisiert und weder die Schaltfläche deaktiviert ist sofort im folgenden Code (getestet auf Nexus 5x), sondern wartet auf den Klick zu bis zum Ende verarbeitet werden! Was ist das, ein Fehler von meiner Seite, ein Fehler oder eine merkwürdige "Optimierungs" -Funktion?Warum wird der Etikettentext nicht sofort geändert?

Page1.xaml:

<?xml version="1.0" encoding="utf-8" ?> 
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
      xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
      x:Class="ModernClientBenchmark.Page1"> 
    <StackLayout> 
    <Button Text="Run the test!" Clicked="OnTestClicked" x:Name="btn"></Button> 
    <Label Text="here we are" x:Name="labl"/> 
    </StackLayout> 
</ContentPage> 

Page1.xaml.cs:

public partial class Page1 : ContentPage 
{ 
    private const int TESTQ = 3; 

    public Page1() 
    { 
     InitializeComponent(); 
    } 

    private async void OnTestClicked(object sender, EventArgs e) 
    { 
     btn.IsEnabled = false; 
     var l1 = new double[TESTQ]; 
     var l2 = new double[TESTQ]; 
     for (int i = 0; i < TESTQ; i++) 
     { 
      Device.BeginInvokeOnMainThread(() => labl.Text = "Step " + i); 
      l2[i] = (await ManagedNetworkSpeedAsync(true)).Milliseconds; 
      //l1[i] = (await NativeNetworkSpeedAsync(true)).Milliseconds; 
     } 

     //var avg1 = l1.Sum()/TESTQ; 
     //var avg2 = l2.Sum()/TESTQ; 

     var a = 234; 

    } 

    public static async Task<TimeSpan> NativeNetworkSpeedAsync(bool secure) 
    { 
     using (var client = new HttpClient(new NativeMessageHandler())) 
     { 
      return await RunTestAsync(secure, client); 
     } 
    } 

    public static async Task<TimeSpan> ManagedNetworkSpeedAsync(bool secure) 
    { 
     using (var client = new HttpClient()) 
     { 
      return await RunTestAsync(secure, client); 
     } 
    } 

    public static async Task<TimeSpan> RunTestAsync(bool secure, HttpClient client) 
    { 
     try 
     { 

      var start = DateTime.Now; 
      for (var i = 0; i <= 1; i++) 
      { 
       var result = client.GetStreamAsync(secure ? "https://xamarin.com" : "http://httpbin.org/ip").Result; 
       result.Dispose(); 
      } 
      return DateTime.Now - start; 
     } 
     catch (Exception ex) 
     { 
      var a = 234; 
     } 
     return new TimeSpan(); 
    } 
} 

Antwort

1

Sie sind bereits auf dem UIThread und blockieren sich selbst, Sie müssen Ihre Arbeit auf den Thread-Pool platzieren und die Benutzeroberfläche von dort aktualisieren, ein await Task.Run Block wird die Aufgabe erledigen.

Dies wird Ihnen die Ergebnisse, die Sie erwarten:

private async void OnTestClicked(object sender, EventArgs e) 
{ 
    btn.IsEnabled = false; 
    var l2 = new double[TESTQ]; 
    await Task.Run(async() => { 
     for (int i = 0; i < TESTQ; i++) 
     { 
      Device.BeginInvokeOnMainThread(() => labl.Text = "Step " + i); 
      l2[i] = (await ManagedNetworkSpeedAsync(true)).Milliseconds; 
     } 
    }); 
    foreach (var x in l2) 
    { 
     System.Diagnostics.Debug.WriteLine(x); 
    } 
    btn.IsEnabled = true; 
} 
1

Da Sie einen asynchronen Vorgang fangen und es mit dem UI-Thread ist synchronisiert, die Das gesamte Label ändert sich erst, wenn der UI-Thread Zeit hat, die gesamte Änderung durchzuführen.

Dies ist das normale Verhalten moderner Anwendungen, bei denen Sie die Benutzeroberfläche nicht für lange laufende Vorgänge blockieren möchten (z. B. asynchrone Vorgänge wie das Anfordern externer Ressourcen über HTTP).

BTW, Sie können Ihre Schaltfläche deaktivieren, bevor Sie den asynchronen Vorgang starten und nach dem Abschluss wieder aktivieren.

+0

ich bin mit 'await' so dass der Code in einem anderen Thread ausgeführt werden soll. Recht? – nicks

+0

@NikaGamkrelidze In deinem Fall, ja, BTW Async/erwarten bedeutet nicht "anderer Thread" an sich. –

+0

also, was sagst du? Wenn der Code in einem anderen Thread ausgeführt wird, warum ist der UI-Thread blockiert? – nicks

Verwandte Themen