2011-07-26 7 views
1

저는 멀티 스레딩에 익숙하지 않았기 때문에 질문이 어리 석었지만이 문제를 해결할 방법을 찾을 수없는 것으로 보입니다 (특히 C#을 사용하고있어 한 달 동안 사용했기 때문에).threadCounter 변수의 동적 개수를 설정하는 방법은 무엇입니까?

동적 인 번호의 디렉토리가 있습니다. DB의 쿼리에서 가져 왔습니다. 이러한 쿼리에는 일정량의 파일이 있습니다.

기본적으로 FTP 최대 연결에 제한이 없기 때문에 각 디렉토리에 대해 FTP를 사용하여 이러한 파일을 전송하는 방법을 사용해야합니다 (내 단어가 아님, 구체적으로 작성되었습니다).

하지만 여전히 파일 당 최대 파일 전송량을 제어해야합니다. 그래서 나는 (증분/감소) 전송하는 파일을 계산해야합니다.

어떻게하면됩니까? 배열과 같은 것을 사용해야하고 모니터 클래스를 사용해야합니까?

편집 : 프레임 워크 3.5

+0

스레드 단위는 무엇입니까? 업로드되는 파일 당 하나의 스레드 또는 디렉토리 당 하나의 스레드? – Unsliced

+0

프레임 워크 타겟은 무엇입니까? '4.0'을 사용하고 있습니까? –

+0

@Unsliced ​​: N 디렉토리 당 스레드. 각 디렉토리에 대해 나는 그때 더 많은 파일을 전송해야한다. – dierre

답변

1

Semaphore 클래스를 사용하여 디렉토리 당 동시 파일 수를 제한 할 수 있습니다. 디렉토리 당 하나의 세마포어가 있어야 디렉토리 당 FTP 업로드 수가 독립적으로 제어 될 수 있습니다.

public class Example 
{ 
    public void ProcessAllFilesAsync() 
    { 
    var semaphores = new Dictionary<string, Semaphore>(); 
    foreach (string filePath in GetFiles()) 
    { 
     string filePathCapture = filePath; // Needed to perform the closure correctly. 
     string directoryPath = Path.GetDirectoryName(filePath); 
     if (!semaphores.ContainsKey(directoryPath)) 
     { 
     int allowed = NUM_OF_CONCURRENT_OPERATIONS; 
     semaphores.Add(directoryPath, new Semaphore(allowed, allowed)); 
     } 
     var semaphore = semaphores[directoryPath]; 
     ThreadPool.QueueUserWorkItem(
     (state) => 
     { 
      semaphore.WaitOne(); 
      try 
      { 
      DoFtpOperation(filePathCapture); 
      } 
      finally 
      { 
      semaphore.Release(); 
      } 
     }, null); 
    } 
    } 
} 
+0

죄송합니다. 3.5에서 일하고 있다는 것을 잊어 버렸습니다. SemaphoreSlim은 4 가지 기능입니다. 실제로는 좋은 기능처럼 보입니다. – dierre

+0

나는 대신'Semaphore'를 사용하기 위해 나의 대답을 편집했습니다. –

+0

정말 멋진 솔루션입니다. 나는 (국가) 구문을 몰랐다. – dierre

0
var allDirectories = db.GetAllDirectories(); 
foreach(var directoryPath in allDirectories) 
{ 
    DirectoryInfo directories = new DirectoryInfo(directoryPath); 
    //Loop through every file in that Directory 
    foreach(var fileInDir in directories.GetFiles()) { 
     //Check if we have reached our max limit 
     if (numberFTPConnections == MAXFTPCONNECTIONS){ 
      Thread.Sleep(1000); 
     } 

     //code to copy to FTP 
     //This can be Aync, when then transfer is completed 
     //decrement the numberFTPConnections so then next file can be transfered. 
    } 
} 

당신은 위의 라인을 따라 뭔가를 시도 할 수 있습니다. 그것은 단지 기본 로직 일 뿐이며,이를 수행하는 더 좋은 방법이 있습니다.

+0

입니다. 아니요, 디렉토리 당 cuncurrently 얼마나 많은 파일을 이동하는지 계산하려면 각 디렉토리에 대한 카운터를 설정해야합니다. – dierre

관련 문제