【问题标题】:How do I update string value from inside a thread如何从线程内部更新字符串值
【发布时间】:2018-06-15 18:43:29
【问题描述】:

我正在编写与用户帐户一起使用的 Xamarin.Forms 跨平台应用程序。问题是我从我的数据库中获取了他们的用户名,但它不会更新 public static string username = ""; 的值

我假设这是因为它在线程内运行或与 WebRequest 有关,我已经安静地进行了一段时间的研究,但未能找到解决方案。

我用来更新用户名的方法如下

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
            {
                Stream stream = request.EndGetResponse(result).GetResponseStream();
                StreamReader reader = new StreamReader(stream);
                Device.BeginInvokeOnMainThread(() =>
                {
                    string page_result = reader.ReadToEnd();
                    var jsonReader = new JsonTextReader(new StringReader(page_result))
                    {
                        SupportMultipleContent = true // This is important!
                    };
                    var jsonSerializer = new JsonSerializer();
                    try
                    {
                        while (jsonReader.Read())
                        {
                            UserData userData = jsonSerializer.Deserialize<UserData>(jsonReader);
                            username = userData.username;
                        }

                    }
                    catch (Newtonsoft.Json.JsonReaderException readerExp)
                    {
                        string rEx = readerExp.Message;
                        Debug.WriteLine(rEx);
                    }
                });
            }
            catch (Exception exc)
            {
                string ex = exc.Message;
                Debug.WriteLine(ex);
            }

        }, null);
    }

打开网址后,会打印出以下行

{"id":7,"username":"TestUser","name":"Test User","bio":"Hello World","private":0}

UserData 包含以下代码

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

我还注意到打印出以下错误,我尝试谷歌搜索并没有找到任何我理解的解决方案来解决这个问题

解析正无穷大值时出错。路径'',第 0 行,第 0 位置。

【问题讨论】:

  • 而不是只写下异常的消息,转储整个异常 (Debug.WriteLine (exc)):这将为您提供异常的整个堆栈跟踪,包括发生错误的代码行:这将帮助您了解您的错误。一般来说,不要吞下异常:您的程序有错误,您只需将其写下来并忽略它:如果以前的方法没有达到预期的效果,您如何程序正常进行?
  • 我试过了,找不到任何异常(调试控制台pastebin.com/hCU4BxVn

标签: c# json multithreading xamarin xamarin.forms


【解决方案1】:

您得到的错误是 JSON.net 错误,发生在 JSON 反序列化期间,这意味着更新静态变量没有问题,因为代码永远不会到达那一点(它以 catch (Newtonsoft.Json.JsonReaderException readerExp) 结尾) .

这很好地缩小了您的问题。您从服务器收到的响应很可能有问题。在var jsonReader = ... 行上放置一个断点并检查page_result 变量的内容以查看它们是否不包含任何意外字符。您还可以将响应转储到 JSON 验证器中,以确认它是否真的有效 (https://jsonlint.com/)

【讨论】:

  • 这有帮助,谢谢!这也是因为它是异步的并且它正在加载一个网页,它在值更新之前已经加载了下一页。
  • 太棒了,很高兴它有帮助。编码愉快!
【解决方案2】:

每个变量都限定在一个内存中,仅用于执行其声明的线程,因此,当您从另一个线程访问该变量时,您正在读取另一个线程内存中的副本.
当线程与另一个线程同步时执行此复制,并不总是仅在设置变量时执行此操作。
因此,您必须在变量声明中添加volatile 修饰符,这表明必须在全局同步范围内分配和释放变量。
尝试像这样声明你的变量:

public static volatile string username = "";

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-08
    • 1970-01-01
    • 2013-08-27
    • 1970-01-01
    • 2020-10-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多