使用Thread.Sleep限制每秒API调用的数量?

时间:2014-07-17 13:56:17

标签: c# xamarin

一如既往,我非常喜欢菜鸟,因为我确信你会从我的代码和问题中看到。对于练习我正在为一款名为Eve Online的游戏编写一个Xamarin.Android应用程序。那里的人们从行星中获取资源以赚取现金。这些地雷必须以不同的间隔重置,真正的专业人员最多可以有30个字符。每个角色可以有5个行星,通常每个角落至少有2个地雷(提取器)。所以可能会有300个计时器继续运行。

在我的应用程序中,您将角色保存在sqlite数据库中,每隔一小时,一个intentservice就会运行API并检查您的时间以及它们是否已过期。这就是我这样做的方式:

public async Task PullPlanets(long KeyID, long CharacterID, string VCode, string CharName)
    {
        XmlReader lesern = XmlReader.Create("https://api.eveonline.com/char/PlanetaryColonies.xml.aspx?keyID=" + KeyID + "&vCode=" + VCode + "&characterID=" + CharacterID);

        while (lesern.Read())
        {
            long planet = 0;
            string planetName;
            planet = Convert.ToInt64(lesern.GetAttribute("planetID"));
            planetName = lesern.GetAttribute("planetName");

            if ((planet != 0) && (planetName != null))
            {
                planets.Add(planet);
                planetNames.Add(planetName);
                await GetExpirationTimes(CharName, planet, planetName, KeyID, CharacterID, VCode);

            }
        }

        lesern.Close ();
    }



    public async Task GetExpirationTimes(string CharName, long planetID, string planetName, long KeyID, long CharacterID, string VCode)
    {
        string planet = planetID.ToString();
        XmlReader lesern = XmlReader.Create("https://api.eveonline.com/char/PlanetaryPins.xml.aspx?keyID=" + KeyID + "&vCode=" + VCode + "&characterID=" + CharacterID + "&planetID=" + planet);


        while (lesern.Read())
        {
            string expTime;
            expTime = lesern.GetAttribute("expiryTime");

            if ((expTime != null) && (expTime != "0001-01-01 00:00:00"))
            {

                    allInfo.Add (new AllInfo (CharName, planetName, Convert.ToDateTime (expTime)));

            }
        }

        lesern.Close ();

        SendOrderedBroadcast (stocksIntent, null);
    }

}

在此之后,它将时间发送回我的A​​ctivity,在那里它们被添加到提取器中。它看起来工作得很好,虽然到目前为止我只能用2个字符和14个提取器进行测试。活动中的闹钟管理器每小时调用该服务,并发送通知。当用户打开活动时,它会从服务中提取列表,对其进行排序并显示它。如果这是这样做的话,我会欢迎你的意见。

但是,我确实看到了一个问题。如果应用程序每秒超过30个API调用,则Eve API会阻止。我很确定有30个角色的人会这样做。所以,我想知道如果传递一定数量我是否应该添加一些东西来延迟每次通话?这就是我调用第一个XML调用的方式。

var table = db.Table<CharsList> ();

    foreach (var e in table) {

        long KeyIDOut = Convert.ToInt64(e.KeyID);
        long CharIDOut = Convert.ToInt64(e.CharacterID);
        string VCodeOut = e.VCode.ToString();
        string navnOut = e.Name.ToString();


            PullPlanets(KeyIDOut, CharIDOut, VCodeOut, navnOut);

        }

        CheckTimes ();

    }

添加

是否可行
 if (table.Count > 10) {

 foreach (var e in table) {
 //start the first characters call
 Thread.Sleep(100)

}

该服务是intentservice而不是UI线程。我想这会使调用低于30秒,但我从未使用Thread.Sleep并担心我的代码中还会发生什么。还有其他事情可以帮助我不受限制吗?这段代码可以处理300个提取器吗?

1 个答案:

答案 0 :(得分:1)

我相信你的态度通常是正确的。我不得不为我写的reddit客户端做类似的事情,除了他们的限制是一秒钟左右。

我看到你设置的唯一问题是假设Thread.Sleep在你给它的时间内睡眠。在某些情况下可能会发生虚假唤醒,所以我建议你给它一个较小的值,保存上次访问服务然后在睡眠调用周围循环,一旦足够的时间过去就终止。

最后,如果您要为相对较短的工作量启动大量的意向服务,您可能希望通过一个线程来处理工作的正常服务 - 这样只需要创建它曾经,但它仍然是UI线程。