[英]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.