2009-09-09 9 views
2

100 개의 문자열 URI가 포함 된 문자열 배열 myDownloadList가 있습니다. 스택 (myDownloadList)에 남아있는 URI가 없을 때까지 스택과 같이 myDownloadList에서 다음 URI를 팝핑하고 스택과 같은 작업을 수행하는 5 스레드 작업을 시작하고 싶습니다.스레드 된 동시 작업

이렇게하는 것이 가장 좋은 방법은 무엇입니까?

답변

6

ThreadPool을 사용하고 모든 요청을 설정하기 만하면됩니다. ThreadPool은 자동으로 적절히 스케쥴합니다.

작업 병렬 라이브러리를 사용하면 .NET 4에서 더 쉽게 얻을 수 있습니다. 각 요청을 Task으로 설정하는 것은 매우 효율적이며 쉽습니다.

+0

"WaitHandles 수는 64 이하 여야합니다."에 ThreadPool이 붙어 있습니다. 오류. – Davorin

+3

아마도 STA를 사용 중이라면 64 개의 대기 핸들에서만 WaitAll (핸들)을 사용할 수 있습니다. 그냥 루프에서 개별적으로 핸들을 개별적으로 기다리십시오. 대신 잘 작동합니다. foreach (핸들에서 var 핸들) handle.WaitOne(); 이 제한 사항은 다음 주소에서 문서화되어 있습니다. http://msdn.microsoft.com/en-us/library/z6w25xa6.aspx –

1

액세스 할 때 각 스레드가 myDownloadList를 잠그도록하십시오. 재귀를 사용하여 최신 항목을 계속 가져올 수 있습니다. 목록이 0이면 함수를 중지 할 수 있습니다.

아래 예를 참조하십시오.

public static List<string> MyList { get; set; } 
public static object LockObject { get; set; } 

static void Main(string[] args) 
{ 
    Console.Clear(); 

    Program.LockObject = new object(); 

    // Create the list 
    Program.MyList = new List<string>(); 

    // Add 100 items to it 
    for (int i = 0; i < 100; i++) 
    { 
     Program.MyList.Add(string.Format("Item Number = {0}", i)); 
    } 

    // Start Threads 
    for (int i = 0; i < 5; i++) 
    { 
     Thread thread = new Thread(new ThreadStart(Program.PopItemFromStackAndPrint)); 

     thread.Name = string.Format("Thread # {0}", i); 

     thread.Start(); 
    } 
} 


public static void PopItemFromStackAndPrint() 
{ 
    if (Program.MyList.Count == 0) 
    { 
     return; 
    } 

    string item = string.Empty; 

    lock (Program.LockObject) 
    { 
     // Get first Item 
     item = Program.MyList[0]; 

     Program.MyList.RemoveAt(0); 
    } 

    Console.WriteLine("{0}:{1}", System.Threading.Thread.CurrentThread.Name, item); 

    // Sleep to show other processing for examples only 
    System.Threading.Thread.Sleep(10); 

    Program.PopItemFromStackAndPrint(); 
} 
+0

재귀 적으로 호출하는 대신 while 루프를 사용하는 것이 좋습니다. 이것은 가능합니다 ... 그렇습니다 ... 스택 오버 플로우를 만듭니다. –

관련 문제