2009-08-18 5 views
3

시간을 많이 소비하는 작업을 수행하기 위해 Backgroudworker를 사용했습니다.BackgroundWorker가 컬렉션 항목에 사용되었습니다.

public void ConnectDataProvider() 
    { 
     bgw = new BackgroundWorker(); 
     bgw.DoWork += new DoWorkEventHandler(bgw_DoWork); 
     bgw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgw_RunWorkerCompleted); 

    } 

또 다른 방법은 백그라운드 작업자가 시작됩니다 : 당신이 볼 수 있듯이

void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     // do it over again 
     StartPolling(); 
    }  

void bgw_DoWork(object sender, DoWorkEventArgs e) 
    { 
     // do work 
     WriteData(); 
    } 

, 나는 완료에 작업자를 통해 시작 :

public void StartPolling() 
    { 
     bgw.RunWorkerAsync(); 
    } 

그럼 내가 이벤트 처리를했다. 이제이 작업은 단일 배경 작업자에게 효과적입니다.

이제 컬렉션이 필요하며 각 항목에서이 작업을 수행해야합니다. 그러나 위의 개념으로 작업자를 시작하기 때문에 시작된 첫 번째 작업자에서 계속 실행됩니다. 나는 타이머가 조합되어 다른 작업자 스레드를 제공 할 수 있다고 생각하고있다.

여전히 BackgroundWorker는 좋은 선택입니까? 내가했던 것처럼 BackgroundWorker를 재사용하는 것이 일반적입니까?

EDIT 1 : clairify하려면 : 내가 직면하고있는 문제는 각각 자신의 BackgroundWorker로 컬렉션을 관리해야한다는 것입니다. 나는 각 항목에서 요청을 주기적으로 시작하기 위해 타이머를 생각하고 있었다. 내가 붙어있는 곳이야.

편집 2 : 본인의 대답을보고이 문제를 해결하지는 못했지만 타이머를 사용하여 내가 원하는 것을 얻을 수 있다는 것을 알았습니다.

EDIT 3 : 달성하기를 원하는 점을 명확히하기 위해 (또 다른 시도, 잘 모르겠다.) 나는 GPS 추적을 위해 추적 개체를 가지고있다. 추적 장치마다 하나의 개체가 있으므로 전체를 추적하려고합니다. 그들은 모두 자주 투표해야합니다. 하나의 테스트 객체에 대해 BackgroundWorker를 설정했는지 확인하십시오. 나는 Backgroundworker가 끝나면 나에게 말해주는 방식을 좋아했다. 하지만 모든 추적 객체로 작업 할 수는 없었습니다.

이제 모든 추적 객체에는 자체 타이머가 있습니다. 이 타이머는 새 스레드를 생성하고 시간 소모적 인 작업을 수행합니다 (이름은 DoWrite 임). 타이머를 처리하고 새 타이머를 만들 때 BackgroundWorker가 필요하지 않습니다. 그게 전부입니다. 여러 시간에 같은 시간에 실행되도록 작업을 소모있을 때

+0

아마도 컬렉션과 타이머 사이에 나타나는 관계를 설명해야합니다. 나는 그 질문에 답할 수 없다. –

답변

4

몇 개가있을 수 있습니까? 컬렉션의 항목과 스레드간에 1 : 1 관계를 만드는 데주의해야합니다. 다른 코더가 사용자가 계획 한 것보다 더 많이 수집하여 확장 할 수 있습니다.

이와 같은 경우에는 보통 하나의 스레드와 대기열을 사용하는 것이 좋습니다. 이벤트는 ConcurrentQueue에서 수행해야하는 작업을 넣기 때문에 스레드가 실행되지 않으면 스레드가 시작되고 그것이 할 일에서 벗어날 때까지 작업 대기. 다음 번에 더 많은 작업이 들어 오면 이벤트가 스레드가 실행 중인지 확인하고 이벤트를 시작합니다.

많은 일이 발생하면 많은 스레드를 중지하고 시작하는 대신 하나의 스레드 만 실행하거나 거의 진행되지 않으면 하나의 스레드가 거의 실행되지 않기 때문에 비용이 적게 듭니다.

+0

이것은 나에게 의미가 있습니다. 고맙습니다. – rdoubleui

0

, 난 당신이 스레드 풀을 사용하는 것이 좋습니다

http://msdn.microsoft.com/en-us/library/ms973903.aspx

+1

BackgroundWorker가 ThreadPool을 내부적으로 사용한다고 생각했습니다. 이것이 내가 BackgroundWorker를 선택한 이유 중 하나이기 때문에 실행중인 스레드의 최대 수를 처리 할 필요가 없습니다. – rdoubleui

+0

@ rdoubleui- 맞습니다. 내부적으로 스레드 풀을 사용합니다. – RichardOD

+0

백그라운드 작업자가 스레드 풀을 사용하고 있지만 백그라운드 작업자 모음을 만들려면 (내가이 방법으로 질문을 이해했습니다) 스레드 컬렉션을 관리하는 개체 모음을 얻을 수 있습니다. 따라서 내 응용 프로그램을 과도하게 사용하고 있습니다. 관점. –

1
그냥 잠시() 루프를 넣어 경우 귀하의 솔루션이 더 논리적 보일 것

Dowork()에서 조금 수면 (어쩌면).

그러면 속도면에서별로 좋지 않을 수도 있지만 여러 Bgw를 실행해도 반대 의견이 없습니다.

+0

그것은 잘 작동하지 않으며, 대부분의 객체를 제외합니다. 어떻게 든 컬렉션의 모든 항목에서 주기적으로 요청해야합니다. – rdoubleui

+1

왜 Bgw/항목을 사용하면 아무 것도 생략하지 않습니까? –

1

당신은 정확하게 당신이 무엇을 설명 할 수 - 당신이 thusly 히, StartPolling에 관련 백그라운드 작업자에 대한 참조를 전달해야합니다

분명히 그런
void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    // do it over again 
    StartPolling((BackgroundWorker)sender); 
} 

public void StartPolling(BackgroundWorker worker) 
{ 
    worker.RunWorkerAsync(); 
} 

, 당신은 BackgroundWorker의 컬렉션을 관리해야 ' 이에 따라.

+0

내 접근 방식은 오히려 모든 항목에 자신의 backgroundworker 개체를 제공하는 것이 었습니다. bg 작업자 컬렉션 관리가 내가 원하는 것입니다. – rdoubleui

0

아무도 지금까지 아무도하지 않았으므로 타이머 접근 방식을 사용합니다.나는 두 가지 (BackgroundWorker와 Timer)를 결합하려고했지만, 그건 의미가 없다.

여러 인스턴스가 스레드별로 데이터를 요청할 수있는 메커니즘이 필요했습니다. 또한 중간에 간격을두고 싶었습니다.

그래서 주위를 시도한 후, 나는 단지 타이머 접근 방식과 함께 얻을 수있는 생각 : 존 손더스가 비슷한 (하지만 다른) 문제에 무엇을 제안했다

public void ConnectDataProvider() 
    { 
     timer = new Timer(new TimerCallback(tCallback), null, 0, Timeout.Infinite);    
    } 

private void tCallback(object state) 
    { 
     timer.Dispose(); 
     // time consuming task 
     WriteData(); 
     timer = new Timer(new TimerCallback(tCallback), null, 5000, Timeout.Infinite); 
    } 

. 그 일을하는 것 같습니다. WriteData()에는 동기 HttpWebRequest가 있으므로 시간 초과를 처리 할 수 ​​있습니다.

내 질문의 현재 : 타이머 개체의 새로운 인스턴스 생성은 얼마나 비쌉니까? 얼마나 비싸다는 뜻인가요? 더 좋은 방법이 있습니까?

참고 : WebRequest의 비동기 접근 방식이 작동하지 않을 것입니다. 지금까지 서버의 방식에 대한 단서가 없습니다.

1

왜 progresschanged 이벤트를 사용하지 않습니까? userstate 객체를 사용하여 데이터를 전달할 수 있습니다.

있음 작업을 수행하기 만하면 장치가 풀링되고 프로세스가 변경되어 데이터가 UI 스레드로 전송됩니다.

중간에 끝내고 취소를 사용하여 해당 스레드를 중지하십시오.

감사합니다.

+0

그게 내가 할 수있는 방법이야. –

관련 문제