Blazor UI锁定

杰德

UPDATE:它是从json到锁定线程的类的转换。我已经尝试过使用较小的数据包进行相同的过程,并且UI并未冻结。那么问题是如何克服呢?

我试图从解析为类的JSON获取值:

 public async Task<BitcoinDetails> GetData()
    {

        return await _httpClient.GetFromJsonAsync<BitcoinDetails>("https://localhost:5001/proxy");

    }

我使用OnInitializedAsync将数据加载到视图中,但是以下代码锁定了UI

_bitcoinDetails = new BitcoinDetails();
        _bitcoinDetails = await _bitcoinApiService.GetData();

        var price = _bitcoinDetails.data.Find(x => x.symbol == "BTC");
        if (price == null)
        {
            _bitcoinPrice = 0;
        }

        _bitcoinPrice = double.Parse(price.quote.USD.price.ToString());

如何在不锁定UI的情况下重组此代码以加载数据?

查看代码:

 @if (_bitcoinDetails == null)
{
    <p><em>Loading...</em></p>
}
else
{
<h3>BTC:@_bitcoinPrice</h3>
}
米尔托

Blazor WebAssembly中的多线程

Blazor WebAssembly还没有真正的多线程支持。所有任务都有效地在与UI相同的线程上运行,这意味着执行任何耗时超过几毫秒的CPU密集型工作都可能导致用户界面出现明显的冻结。

不幸的是,直到.NET 6(2021年11月),Blazor WebAssembly中的多线程情况才可能得到改善。在此之前,解决方法是将短暂的暂停手动引入到CPU密集型任务的流程中,以便UI可以在这些中断期间控制并完成其工作:

async Task PerformCpuIntensiveWorkAsync()
{
    for (int i = 0; i < 100; i++)
    {
        PerformOneHundredthOfWork();
        await Task.Delay(1);
    }
}

大型JSON的反序列化

大多数JSON序列化程序提供低级API,可让您完全控制反序列化过程:

例如,如果需要反序列化大型JSON,其中包含100,000个汽车的数组

[
  { "make": "Ford", "model": "Mustang", "year": 2000 },
  { "make": "Honda", "model": "Civic", "year": 2005 },
  { "make": "Chevrolet", "model": "Corvette", "year": 2008 },
  ...
]

https://api.npoint.io/d159a22063995b37c52d下载此JSON

这是使用JSON.Net可以在反序列化过程中引入短暂休息的方法

using Newtonsoft.Json;
using System.IO;

...

public class Car
{
    public string Make { get; set; }
    public string Model { get; set; }
    public int Year { get; set; }
}

...

using var jsonStream = await Http.GetStreamAsync("https://api.npoint.io/d159a22063995b37c52d");

List<Car> cars = await DeserializeCarsAsync(jsonStream);

static async Task<List<Car>> DeserializeCarsAsync(Stream jsonStream)
{
    using var streamReader = new StreamReader(jsonStream);
    using var jsonReader = new JsonTextReader(streamReader);
    var serializer = new JsonSerializer();

    if (!jsonReader.Read())
        throw new JsonException($"Deserialization failed at line {jsonReader.LineNumber} position {jsonReader.LinePosition}.");
    if (jsonReader.TokenType != JsonToken.StartArray)
        throw new JsonException($"Deserialization failed at line {jsonReader.LineNumber} position {jsonReader.LinePosition}.");

    List<Car> cars = new List<Car>();
    while (true)
    {
        if (!jsonReader.Read())
            throw new JsonException($"Deserialization failed at line {jsonReader.LineNumber} position {jsonReader.LinePosition}.");
        if (jsonReader.TokenType == JsonToken.EndArray)
            return cars;
        if (jsonReader.TokenType != JsonToken.StartObject)
            throw new JsonException($"Deserialization failed at line {jsonReader.LineNumber} position {jsonReader.LinePosition}.");

        var car = serializer.Deserialize<Car>(jsonReader);
        cars.Add(car);

        // Pause after every 10th deserialized car:

        if (cars.Count % 10 == 0)
            await Task.Delay(1);
    }
}

如果您必须处理嵌套集合,它看起来确实过于复杂,甚至变得更糟,但是它解决了这个问题。

其他选择

  • 如果可能,使用较小的JSON。看来您正在使用代理从CoinMarketCap获取报价或列表。您可以获得整个列表,但只需要一项-BTC。在不知道详细信息是否适合您的情况下很难说,但是有可能要求CoinMarketCap服务器为您过滤结果并仅返回BTC报价的数据-这将产生更小的JSON:https:// sandbox -api.coinmarketcap.com/v1/cryptocurrency/quotes/latest?CMC_PRO_API_KEY=b54bcf4d-1bca-4e8e-9a24-22ff2c3d462c&symbol=BTC

  • 尝试更快的JSON序列化器。Utf8Json看起来很有希望

  • 如果您只需要从大型JSON反序列化一些字段,则有许多潜在的优化方法:

    • 尝试反序列化为具有较少字段的类。例如,如果您反序列化Quote对象并且只需要获取其价格,请尝试使用具有only属性的类Price反序列化为:class Quote { decimal Price {get; set;} }
    • 尝试使用JsonDocument仅反序列化所需的特定JSON节点虽然仍然需要先解析整个JSON才能创建其节点的映射,但是无论如何,它应该比反序列化整个JSON更快。
    • 如果您使用序列化器的低级API,则大多数都允许在解析时跳过JSON元素(JsonReader.SkipUtf8JsonReader.SkipJsonReader.ReadNextBlock等)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

在Blazor中延迟任务而不阻塞UI

来自分类Dev

即使使用Task,Blazor UI也会冻结

来自分类Dev

使用Blazor重写JavaScript单击并显示UI

来自分类Dev

Blazor Webassembly在UI中显示错误的时间

来自分类Dev

如何正确通知Blazor UI我的用户状态已更改?

来自分类Dev

服务器端Blazor验证未更新UI

来自分类Dev

为什么Blazor UI组件在删除事件后不更新?

来自分类Dev

Blazor:在ui更新时执行无关的代码块

来自分类Dev

为Blazor UI应用程序实施防伪验证

来自分类Dev

Blazor Server:手动刷新重新呈现的UI

来自分类Dev

ABP.IO Blazor UI模板非常慢

来自分类Dev

Blazor客户端UI更新未反映

来自分类Dev

Blazor UI更新异步无效与异步任务

来自分类Dev

Blazor.net UI 不呈现任何内容

来自分类Dev

取消TabPage.Validating锁定我的UI

来自分类Dev

Swift UI-锁定和解锁ScrollView

来自分类Dev

添加控件时锁定winform UI

来自分类Dev

登录错误时如何避免锁定UI?

来自分类Dev

在Blazor客户端应用(剃刀组件)中,触发的每个事件是否都会刷新UI?

来自分类Dev

Blazor可以在没有任何UI引用或代码的情况下创建wasm模块吗?

来自分类Dev

Blazor WebAssembly:如何在长时间运行的非异步过程中更新UI

来自分类Dev

Blazor服务器端-子功能中的值更改未更新UI

来自分类Dev

向UI添加内容时如何停止UI锁定

来自分类Dev

全屏Blazor

来自分类Dev

Blazor的问题

来自分类Dev

Blazor InputRadio

来自分类Dev

从Blazor客户端中长期运行的后台任务中释放UI的推荐方法是什么

来自分类Dev

UI中显示的图像将锁定源文件

来自分类Dev

调用alert()时,调用[JSValue callWithArguments:]会锁定UI

Related 相关文章

热门标签

归档