문제

나는 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();
}

제가하려는 것은 플레이어 통계를 포함하는 직렬화 된 PHP 데이터를 가져 오는 약 50 개의 스레드가 진행되는 것입니다. 사용자 0부터 사용자 ID까지 (300,000)을 지정합니다. 내 질문은 통계를 가져 오는 방법에 관한 것이 아니라 통계를 얻고 읽는 방법을 알고있는 것이 아니라 다른 스레드의 발가락을 밟지 않고 300,000 번째 사용자 ID에 도달 할 때까지 통계를 계속 가져 오는 스레드 풀을 작성하는 방법입니다. 통계를 데이터베이스로 검색 할 때 통계를 저장합니다.

도움이 되었습니까?

해결책

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에 의존하여 통화 속도를 스로틀로 사용하고 있으며, 실패한 통화에 대한 재 시도 정책이 없으며 오류 조건 (웹 호출이 실패한 경우)에서 응용 프로그램이 극도로 나빠질 것입니다.

먼저 Async webRequest를 사용하는 것을 고려해야합니다. BegingetrequestStream (귀하가 게시하고 요청 본문이있는 경우) 및/또는 Begingetresponse. 이러한 방법은 훨씬 더 잘 확장되며 CPU가 적은 시간에 더 높은 트로프를 얻을 수 있습니다 (물론 백엔드가 유지 될 수있는 경우).

둘째, 자체 열매를 고려해야합니다. 비슷한 프로젝트에서 나는 보류중인 요청 수를 사용했습니다. 성공시, 각 통화는 스로 틀링 카운트와 함께 2 개의 전화를 더 제출합니다. 실패시 전화는 아무것도 제출하지 않습니다. 전화가 보류 중이 아닌 경우 타이머 기반의 재시도는 매 순간 새 통화를 제출합니다. 이렇게하면 서비스가 다운 될 때 분당 한 번만 시도하여 트랙션과의 회전에서 자신의 자원을 저장하고 서비스가 UP에있을 때 처리량을 스로 틀링 캡까지 다시 증가시킵니다.

또한 .NET 프레임 워크는 모든 리소스에 동시에 동의 한 수를 제한 할 것임을 알아야합니다. 목적지를 찾아야합니다 서비스 포인트 그리고 변경 ConnectionLimit 기본값 (2)에서 최대 값으로 스로틀을 기꺼이 켜고 있습니다.

데이터베이스 업데이트 부분에 대해, 많은 변수에 대한 방법이 있으며 의미가 많은 조언을 제공하기에는 정보가 너무 적습니다. 일반적인 조언은 데이터베이스 호출에서 비동기 메소드를 사용하는 것입니다. 크기 Yoru Conneciton Pool은 스로 틀링 캡을 허용하기 위해 크기를 조정하십시오. 업데이트가 플레이어 ID를 키로 사용하여 다른 스레드에서 동일한 레코드를 업데이트 할 때 교착 상태를 사용하지 않도록하십시오. .

다른 팁

사용자 ID를 어떻게 결정합니까? 한 가지 옵션은 모든 스레드를 세그먼트하여 스레드 X가 ID를 0 -n에서 처리하는 것 등을 몇 개의 스레드 수의 일부로 처리하는 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top