【问题标题】:How to consistently receive and use data from API?如何始终如一地接收和使用来自 API 的数据?
【发布时间】:2021-03-16 11:32:11
【问题描述】:

我对 c# 非常陌生,为了学习如何使用 API,我正在为 Minecraft 制作用户名可用性检查器。我写了一个半工作的检查器代码:

public async Task GetMojangItems(string username)
{
        string response = await client.GetStringAsync("" +
            "https://api.mojang.com/users/profiles/minecraft/" + username);

        if (response.Contains("name") == true)
        {
            Console.ForegroundColor = Color.Red;
            Console.WriteLine(" [-] " + username + " -> " + response);
        }
        else if (response.Contains("name") == false)
        {
            Console.ForegroundColor = Color.Green;
            Console.WriteLine(" [+] " + username + " -> " + response);
        }
}

以及使用它的函数:

private async void CheckUsernames()
{
        Console.WriteLine("");
        Console.WriteLine("Username Checker Selected!");
        Console.WriteLine("1) Test username");
        Console.WriteLine("2) Import username list");
        Console.Write("\r\nSelect an option: ");

        if (Console.ReadLine() == "1")
        {
            Console.Write("\r\nChoose a name to check: ");
            Program program = new Program();
            string nameimput = Console.ReadLine();
            await program.GetMojangItems(nameimput);
        }
}

但是没有得到可靠的结果,有时检查器会响应(大约 10% 的时间),大多数时候它根本不会响应并且会跳过名称。

此外,我似乎必须在主任务中包含一个额外的检查,否则根本不会有任何检查;

await program.GetMojangItems("closingprogram!");

非常感谢有关 API 的任何帮助,如何解决我对 API 数据的读取问题以始终如一地工作?

// 对不起,如果问题难以理解,我不擅长解释问题...

Working result of the checker

Failed result of the checker

【问题讨论】:

  • CheckUsernamesvoid,所以不能等待。这可能是您的问题的原因 -> 返回 Task 并等待。
  • 除此之外,风格评论:if (response.Contains("name") == true) 通常简单写成if (response.Contains("name"))
  • void 只能用于异步事件处理程序:docs.microsoft.com/en-us/dotnet/csharp/programming-guide/…
  • 谢谢,它似乎工作得更多,但它偶尔仍会跳过名称,我已将 void 更新为 Task 并从 response.Contains 中删除了 true
  • 是否在等待 every async 方法? async 应该上升到调用堆栈的顶部:不应该有 async void 方法。

标签: c# json api


【解决方案1】:

快速查看官方 Mojang API 文档,并将其与您编写的代码进行比较,我注意到缺少整个身份验证部分。 Minecraft 从 1.6 版本开始,引入了一个名为 Yggdrasil 的新方案,它完全取代了旧方案。看一下,“匿名”调用可能会有一些限制。

【讨论】:

  • 不只是为了登录帐户吗?我读到匿名电话有 600 个请求/10 分钟
【解决方案2】:

async 与void 一起使用不是创建async 方法的正确方法,始终使用async Task,此外您可以简单地使用

program.GetMojangItems(nameimput).GetAwaiter().GetResult();

【讨论】:

  • 我会用它来代替什么?
  • 私有异步任务 CheckUsernames()
  • 如果您想从同步方法调用async Task,您可以这样做。但是,如果您可以避免这样做,请坚持使用异步方法并且不要这样做。从同步方法调用异步方法并不总是“很好”。你可以引入死锁,我已经看到它们以其他方式失败。当您坚持async 时,您将不必解决这些问题。
  • 这方面的文章也很多。这是docs.microsoft.com/en-us/archive/msdn-magazine/2013/march/… 出现的第一个。虽然这是从 2013 年开始,但 API 没有改变,即使他们改变了概念也没有改变。这也不是 C# 问题,您会在其他具有异步编程的语言中看到同样的情况,例如 kotlins 协程。
猜你喜欢
  • 1970-01-01
  • 2017-08-13
  • 1970-01-01
  • 2018-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-21
  • 2023-02-12
相关资源
最近更新 更多