You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在线程内更新Xamarin.Forms中的静态字符串值?

解决Xamarin.Forms中用户名更新失败与JSON解析报错的问题

首先咱们先搞定那个棘手的JSON解析报错:Error parsing positive infinity value. Path '', line 0, position 0.,这个问题大概率是流读取的线程时机错误导致的。你当前代码把reader.ReadToEnd()放在了Device.BeginInvokeOnMainThread的委托里,但响应流的读取必须在发起Web请求的后台线程完成——流对象并非线程安全,跨线程读取极易引发数据异常,进而出现这类奇怪的解析错误。

而静态username无法更新的问题,一方面和JSON解析失败直接相关(解析出错就不会执行username = userData.username),另一方面也可能是异步操作的时序问题导致的。

具体修复步骤:

1. 调整流读取的线程位置

把StreamReader.ReadToEnd()移到后台线程(BeginGetResponse回调内部、Device.BeginInvokeOnMainThread外部),先完整读取响应内容,再把字符串传到主线程解析JSON:

private void loadUserData() 
{
    username = "Test"; // 这行同步赋值会立刻生效,但异步请求的赋值需等待请求完成
    Uri uri = new Uri("http://example.com/session-data.php?session_id=" + session);
    WebRequest request = WebRequest.Create(uri);
    
    request.BeginGetResponse((result) => 
    {
        try 
        {
            using (var response = request.EndGetResponse(result))
            using (var stream = response.GetResponseStream())
            using (var reader = new StreamReader(stream))
            {
                // 先在后台线程读取完整响应文本
                string page_result = reader.ReadToEnd();
                
                // 切换到主线程处理JSON解析与变量更新
                Device.BeginInvokeOnMainThread(() => 
                {
                    try 
                    {
                        var jsonSerializer = new JsonSerializer();
                        // API返回单个JSON对象,无需循环读取
                        UserData userData = jsonSerializer.Deserialize<UserData>(new JsonTextReader(new StringReader(page_result)));
                        if (userData != null)
                        {
                            username = userData.username;
                            Debug.WriteLine($"用户名已更新为:{username}");
                        }
                    } 
                    catch (Newtonsoft.Json.JsonReaderException readerExp) 
                    {
                        string rEx = readerExp.Message;
                        Debug.WriteLine($"JSON解析错误:{rEx}");
                    }
                });
            }
        } 
        catch (Exception exc) 
        {
            string ex = exc.Message;
            Debug.WriteLine($"请求错误:{ex}");
        }
    }, null);
}

2. 修正JSON反序列化逻辑

你的API返回的是单个JSON对象,不需要设置SupportMultipleContent = true,也不需要while (jsonReader.Read())循环——这个循环会尝试读取多个JSON对象,反而会引发解析错误,直接反序列化到UserData对象即可。

3. 解决异步时序问题

如果调用loadUserData()后立刻访问username,此时异步请求还未完成,读取到的还是初始值或临时的"Test"。建议改用async/await模式替代旧的BeginGetResponse,确保请求完成后再继续后续操作:

private async Task loadUserDataAsync() 
{
    username = "Test";
    Uri uri = new Uri("http://example.com/session-data.php?session_id=" + session);
    
    try 
    {
        using (var client = new HttpClient())
        {
            string page_result = await client.GetStringAsync(uri);
            UserData userData = JsonConvert.DeserializeObject<UserData>(page_result);
            if (userData != null)
            {
                username = userData.username;
                Debug.WriteLine($"用户名已更新为:{username}");
            }
        }
    } 
    catch (Exception exc) 
    {
        Debug.WriteLine($"错误:{exc.Message}");
    }
}

调用时使用await loadUserDataAsync();,就能保证请求完成后再读取username。

4. 确保UserData类的可访问性

当前你的UserData类是默认的internal访问级别,Newtonsoft.Json反序列化内部类可能出现问题,改为public类更稳妥:

public class UserData 
{
    [JsonProperty("id")]
    public int id { get; set; }
    
    [JsonProperty("username")]
    public string username { get; set; }
    
    [JsonProperty("name")]
    public string name { get; set; }
    
    [JsonProperty("bio")]
    public string bio { get; set; }
    
    [JsonProperty("private")]
    public int isPrivate { get; set; }
}

总结

  • 流读取必须在后台线程完成,禁止跨线程到主线程读取
  • 单个JSON对象无需循环反序列化,移除多余的循环和配置
  • 使用async/await保证异步操作的时序,避免读取未更新的变量
  • 确保UserData类为public,避免序列化失败

按照这些步骤修改后,应该就能解决JSON解析报错和用户名无法更新的问题了。

内容的提问来源于stack exchange,提问作者Kingbluesapphire

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:29:16