2017-05-24 3 views
-5

나는 스레드하기로 선택한 응용 프로그램이 있습니다. 이 배후의 목적은 응용 프로그램의 속도를 높이기 위해 여러 스레드를 동시에 실행하는 것입니다.C# 스레드 비동기 처리

현재 응용 프로그램 설정을 반복하고 각 설정에 대한 스레드를 만든 다음 각 설정을 시작하고 모두 참여할 때 알릴 수 있도록 가입하십시오.

이 작업을 수행 할 때 각 스레드는 동 기적으로 실행되어 목적을 달성하지 못합니다.

조인을 제거하기 위해이를 변경할 수 있지만 모든 스레드가 완료 될 때이를 확인할 수 없습니다 (모두 완료되면 실행할 단일 프로세스가 있습니다).

스레딩이 나를위한 것이 아니라, 스레딩 작업이나 병렬 처리 작업을 더 많이보아야한다는 생각이 들기 시작합니다.하지만이 중 하나의 복잡성에 대해서는 확신 할 수 없습니다. 내가 전에 하나 메커니즘을 사용 (그리고 유일한 스레드 다뤄) 아래

현재이 하나씩 스레드를 실행, 현재 나의 스레드

foreach (SettingsProperty value in Properties.Settings.Default.Properties) 
{ 
    //parse out the line in the settings 
    if (value.Name.ToString() != <<criteria>>) 
    { 
     //this is one that we want to do something with 
     sett = value.DefaultValue.ToString().Split(stringSeparators, StringSplitOptions.None); 

     //set the directory 
     Directory.CreateDirectory(<<directory>>); 

     //fire the thread to retrieve the image form the url 
     ThreadWithState tws = new ThreadWithState(<<parameters>>); 
     Thread t = new Thread(new ThreadStart(tws.ThreadProc)); 
     t.Start(); 
     t.Join(); 

    } 
} 
UploadFiles(); 

급부상 코드 조각이며, 다음 마지막 프로세스를 실행하지 않은 . t.join 호출을 제거하면 비동기 스레드가 실행되지만 모든 스레드가 완료되기 전에 업로드가 실행됩니다.

나도 (I이 작동 생각하지만, 더 이해가 없음) 또는 일부 threading.tasks 내가 그렇게 기능을 구현하는 Parallel.ForEach를 구현하는 모든 스레드가 끝날 때까지 기다리거나 이 코드를 변경할 수있는 방법 (나는 또한 작동 할 수 생각하지만 이해가 없다)를 Task.WhenAll 방법

+1

왜 't.Join()'을 부르시겠습니까? –

+1

귀하의 질문이 너무 광범위합니다. 여러 가지를 동시에 실행할 수있는 유효한 방법이 많이 있습니다. 귀하의 코드는 그러한 방법을 시도하지 않습니다. 방금 시작한 스레드에서 즉시 Join()을 호출하면 현재 스레드가 완료 될 때까지 다른 스레드를 시작하지 않습니다. 다른 스레드를 시작하기 전에 기다리지 않으려면 ** 기다리지 말고 **. –

+4

올바른 도구가 무엇인지 알면 비동기 워크 플로우를 구축 할 수 있으며이를 수행하는 방법을 모를 수 있습니다. 그래서 * 어떻게하는지 배우십시오 *. 튜토리얼 사이트가 아닙니다. 병렬 및 비동기 워크 플로우에 대한 많은 자습서가 있습니다. 가서 하나가! 이런 IO 바인딩 작업의 경우 비동기 워크 플로에 대해 배우기 시작합니다. 여러 스레드를 포함 할 필요가 없습니다. –

답변

0

Thread.Join()를 사용할 수있는 것은 (대기) 차단 다른 스레드가 작업을 완료 할 때까지 할 수있는 실행 스레드를 지시한다.

그래서이

t.Start(); 
t.Join(); 

그대로 작업을 시작하고 끝날 때까지 아무것도하지 않는 것을 의미한다.

Parallel.ForEach을 사용하려면 원하는 작업 목록을 만들어야합니다. 을 통해 열거 나 루프 할 수 있습니다 모음 - 예를 들어,

var properties = Properties.Settings.Default.Properties 
    .Where(property => Name != "whatever"); 

지금 propertiesIEnumerable<SettingsProperty>입니다.

지금 당신은이 작업을 수행 할 수 있습니다

Parallel.ForEach(properties, (property) => 
    { 
     // do something with the property. 
    }); 

이 본질적으로 동시 스레드 루프의 반복이 수도 실행 것을 제외하고

foreach(var property in properties) 
{ 
    // do something with the property. 
} 

과 동일합니다. 작업 스케줄러가 작업 부하 및 사용 가능한 것에 따라 스레드를 사용하기 때문에 "5 월"입니다.

-3

모양에서 한 번에 웹 서버에서 여러 이미지를 다운로드하려고합니까?

모든 스레드를 한 번에 (현재 수행 중이지만 thread.join()없이) 시작하고 모든 항목을 목록에 넣습니다. foreach (UploadFiles() 전) 이후 모든 스레드가 중지 될 때까지 목록을 반복적으로 반복합니다. 이렇게하면 현재 작업/다운로드가 완료 될 때까지 실행을 차단하지 않고 모든 작업이 완료 될 때까지 실행을 차단하는 효과가 있습니다.

bool stillRunning = true; 
while(stillRunning) 
    stillRunning = false; 
    foreach(Thread thr in threadList) 
     if(thr.IsAlive) 
      stillRunning = true; 

UploadFiles(); 
+1

이것은 끔찍한 충고이므로 그것을해서는 안됩니다. 먼저, 왜 IO 바인딩 작업을 작업자 스레드에 할당합니까? 이 모든 작업은 * 하나의 스레드에서 수행 할 수 있습니다. 둘째, 여러 스레드에 작업을 할당하려는 경우 작업 병렬 라이브러리를 사용하여 작업을 할당하고 작업이 완료되면 알아낼 수 있습니다. 셋째, 스레드가 폴링되었는지 확인하기 위해 스레드를 폴링하지 않습니다. 이것은 현대 멀티 스레드 운영 체제입니다. 많은 쓰레드가 완료되기를 기다리고 싶다면 그렇게 할 수있는 많은 * 올바른 메커니즘이있다. –

+0

Eric에게 의견을 보내 주셔서 감사합니다. 저는 이것이 최적의 솔루션과 거리가 멀다는 것을 알고 있으며, 제공되는 다양한 라이브러리와 언어 기능을 사용해야한다고 생각합니다. 그러나 나는 또한 가장 빠르고 가장 쉬운 코드가 어떤 상황에서 가장 잘 작동한다는 생각의 기차에 속합니다. 많은 수의 스레드가 완료되었는지를 판별하는 "올바른"메커니즘은 무엇입니까? 단순히 반복적으로 폴링하는 것보다 낫습니다. 대체 방법에 대해 많이 알지 못하기 때문에 코드를 변경하여 차단하지 않도록 답변했습니다. 한 가지 문제에 대한 많은 해결책이 있습니다. – TheWhoAreYouPerson

+1

* 여러 스레드의 제어 *로 프로그램의 정확한 분석 * - 분석하기가 어렵고 악의적으로 생산성이 떨어지는 프로그램 *은 절대적으로 코드화되지 않은 아마추어에 의해 코딩되지 않아야하는 프로그램입니다 * 코드 작성에 가장 빠른 것이 무엇이든간에 기초를 이해합니다. 이것이 프로그래밍에 대한 태도라면, 그 태도가 수익성이있는 많은 종류의 프로그래밍 작업이 있습니다. 멀티 스레드 제어 흐름은 그 중 하나가 아닙니다. –