繁体   English   中英

为什么标签文本没有立即更改?

[英]Why isn't the label text changed instantly?

我尝试测试ModernHttpClient的速度时,遇到以下问题:在以下代码中(该标签未在Nexus 5x上进行测试),标签未更新且按钮均未禁用,而是等待处理点击直到最后! 那是什么,我个人的错误,错误或怪异的“优化”功能?

的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();
    }
}

由于您正在启动异步操作并将其与UI线程同步,因此整个标签不会更改,直到UI线程有时间执行整个更改为止。

这是现代应用程序的常规行为,在这种情况下,您不想为长时间运行的操作(例如,通过HTTP请求外部资源之类的异步操作)而阻塞UI。

顺便说一句,您可以在启动异步操作之前禁用按钮,并在完成异步操作后再次启用它。

您已经在UIThread上并且正在阻塞自己,您需要将工作放到线程池上并从那里更新UI, await Task.Run块将完成此工作。

这将为您提供预期的结果:

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;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM