繁体   English   中英

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

[英]Restrict number of API calls per second with Thread.Sleep?

与往常一样,我是菜鸟,相信您将从我的代码和问题中都看到。 为了练习,我目前正在为名为Eve Online的游戏编写Xamarin.Android应用。 那里的人从行星上开采资源来赚钱。 这些地雷必须在不同的时间间隔进行重置,而真正的职业玩家最多可以使用30个角色来进行重置。 每个角色可以有5个星球,通常每个星球上至少有2个地雷(提取器)。 因此,可能有300个计时器在运行。

在我的应用程序中,您将角色保存在sqlite db中,并且每小时都有一个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);
    }

}

在此之后,它将时间发送回我的活动,然后将它们添加到提取程序中。 到目前为止,尽管我只能用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个提取器吗?

我相信您通常是正确的。 我必须为正在编写的reddit客户做类似的事情,除了他们的限制大约是每秒一次。

我在安装程序中看到的唯一问题是,假设Thread.Sleep确实在给它的时间内睡眠。 在某些情况下,可能会发生虚假唤醒,所以我建议您给它一个较小的值,保存上次访问该服务的时间,然后围绕睡眠调用循环,一旦经过足够的时间便终止。

最后,如果您打算为相对较少的工作量提供大量的意图服务,则您可能希望有一个带有线程来处理工作的普通服务-这样,它只需创建一次即可,但是仍然是UI线程。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM