Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用线程限制每秒的API调用数。睡眠?_C#_Xamarin - Fatal编程技术网

C# 使用线程限制每秒的API调用数。睡眠?

C# 使用线程限制每秒的API调用数。睡眠?,c#,xamarin,C#,Xamarin,和往常一样,我是个不折不扣的人,我相信你会从我的代码和问题中看到这一点。为了练习,我目前正在为一款名为Eve Online的游戏编写一个Xamarin.Android应用程序。那里的人们从行星上开采资源来赚钱。这些地雷必须在不同的时间间隔重置,真正的职业选手最多可以有30个角色来重置。每个角色可以有5颗行星,通常每个行星上至少有2颗地雷(抽取器)。所以可能有300个计时器在运行 在我的应用程序中,您将字符保存在sqlite数据库中,每小时都会有一个intentservice运行API,检查您的时

和往常一样,我是个不折不扣的人,我相信你会从我的代码和问题中看到这一点。为了练习,我目前正在为一款名为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);
    }

}
在此之后,它将时间发送回我的活动,并将它们添加到提取器中。虽然到目前为止,我只能用14个提取器测试2个字符,但它似乎工作得很好。活动中的AlarmManager每小时调用一次服务,并发送通知。当用户打开活动时,它会从服务中提取列表,对其进行排序并显示它。如果这是解决问题的方法,我欢迎大家提供意见

不过,我确实看到了一个问题。如果一个应用每秒超过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 ();

    }
}


该服务是intentservice,不在UI线程上。我想这会使调用速度低于每秒30次,但我从来没有使用过线程。睡觉吧,担心代码中还会发生什么。有没有其他东西可以帮助我不突破极限?这个代码能处理300个提取器吗

我相信你的方法大体上是正确的。我不得不为我正在编写的reddit客户端做类似的事情,除了它们的限制是每秒一次左右

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


最后,如果您要在相对较短的时间内启动大量的intent服务,您可能希望有一个带有线程的正常服务来处理该工作-这样,它只需创建一次,但仍然是UI线程的一部分。

XmlReader
实现了
IDisposable
,因此最好在
使用
块中处理它的使用。谢谢!我会马上实施的!谢谢你的回答和想法。你的解决方案听起来更简单。我意识到睡眠的问题使它变得不准确,我的想法是,即使有打嗝,也可能很容易将其保持在每秒30次以下——如果它是合法的话。我将对这两种方法进行一些认真的测试。我最初是将服务作为服务构建的,但我遇到了很多小问题。现在,从activity或alarmmanager发送意图,然后由intentservice完成所有工作。我没有足够的技能来充分理解这里的利弊。今天我遇到了这个:限制利率的绝佳工具。今晚用200颗行星测试了这个应用程序,它似乎可以正常工作!
 if (table.Count > 10) {

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