簡體   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