![](/img/trans.png)
[英]C# - using Thread.Sleep() to get my cycle run several hundred times per second
[英]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.