0

我已经阅读并查看了很多关于 Threadpooling 的示例,但我似乎无法按照我需要的方式理解它。我设法得到的工作并不是我真正需要的。它只是在自己的线程中运行该函数。

public static void Main()
    {
        while (true)
        {
            try
            {
                ThreadPool.QueueUserWorkItem(new WaitCallback(Process));
                Console.WriteLine("ID has been queued for fetching");
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error: " + ex.Message);
            }
            Console.ReadLine();
        }
    }

public static void Process(object state)
{

    var s = StatsFecther("byId", "0"); //returns all player stats
    Console.WriteLine("Account: " + s.nickname);
    Console.WriteLine("ID: " + s.account_id);
    Console.ReadLine();
}

我想要做的是有大约 50 个线程(可能更多)来获取包含玩家统计信息的序列化 php 数据。从用户 0 一直到我指定的用户 ID (300,000)。我的问题不是关于如何获取统计信息我知道如何获取统计信息并阅读它们,而是我如何编写一个线程池,它将继续获取统计信息直到它达到第 300,000 个用户 ID 而不会踩到其他线程的脚趾和在检索到数据库时保存统计信息。

4

2 回答 2

3
static int _globalId = 0;
public static void Process(object state)
{    
  // each queued Process call gets its own player ID to fetch
  processId = InterlockedIncrement(ref _globalId); 
  var s = StatsFecther("byId", processId); //returns all player stats 

  Console.WriteLine("Account: " + s.nickname);    
  Console.WriteLine("ID: " + s.account_id);    
  Console.ReadLine();
}

这是最简单的事情。但远非最佳。您正在使用同步调用,您依赖 ThreadPool 来限制您的调用速率,您没有针对失败调用的重试策略,并且您的应用程序在错误条件下(当 Web 调用失败时)表现得非常糟糕。

首先,您应该考虑使用 WebRequest 的异步方法:BeginGetRequestStream(如果您 POST 并且有请求正文)和/或BeginGetResponse。这些方法可以更好地扩展,并且您将以更少的 CPU 获得更高的吞吐量(当然,如果后端可以跟上)。

其次,您应该考虑自我节制。在一个类似的项目中,我使用了挂起的请求计数。成功后,每个调用将再提交 2 个调用,并以限制计数为上限。调用失败时不会提交任何内容。如果没有呼叫待处理,则基于计时器的重试每分钟提交一个新呼叫。这样,当服务关闭时,您每分钟只尝试一次,从而节省您自己的资源,避免在没有牵引力的情况下旋转,并在服务启动时将吞吐量增加到限制上限。

您还应该知道,.Net 框架将限制它对任何资源的并发连接数。您必须找到您的目标ServicePoint并将ConnectionLimit从其默认值 (2) 更改为您愿意限制的最大值。

关于数据库更新部分,有很多变量在起作用,而且信息太少,无法提供任何有意义的建议。一些一般性建议是在数据库调用中也使用异步方法,大小 yoru 连接池以允许您的限制上限,确保您的更新使用玩家 ID 作为键,这样您就不会在从不同线程更新相同记录时陷入僵局.

于 2009-09-10T01:24:36.240 回答
0

如何确定用户 ID?一种选择是将所有线程分段,以便线程 X 处理从 0 到 N 的 ID,依此类推,作为您拥有的线程数的一小部分。

于 2009-09-10T00:38:19.203 回答