2009-03-05 4 views
4

새 스레드에서 작업을 시작하거나 백그라운드 작업자를 사용하여 작업을 수행하려고합니다.하지만 이전에이 작업을 수행하고 어떻게해야하는지 묻습니다.새 스레드로 클래스를 실행 중입니다.

내 프로그램에는 파일 목록 (행당 하나의 파일)이있는 DataGridview가 있습니다. 사용자가 행을 선택한 다음 "다운로드 시작"을 눌러 다운로드의 백그라운드 작업을 시작할 수 있기를 바랍니다. 다운로드 진행 상황을 이벤트로 되돌리고 싶습니다.

모든 것을 처리하고 이벤트를 발생시키는 clsDownload 클래스가 있지만 어떻게 backgroundworking을 구현합니까?

클래스 내부에서 System.ComponentModel.BackgroundWorker를 사용하거나이 클래스를 처리하거나 다른 스레딩 재료를 사용하는 래퍼를 만들어야합니까?

감사합니다.

편집 : 내가 backgroundworker에서 다운로드를 구현하는 방법을 이해하지 못한다면, 작은 예제가 아주 좋을 것입니다. msdn didnt에 대한 예제는 저를 멀리합니다.

다운로드 클래스에는 StartDownload 기능이 있습니다. 수업 중이나 발신자에게 backgroundworker를 사용해야합니까? "바보 같은 느낌"

답변

1

BackgroundWorker를 통합 한 여러 클래스를 만들었습니다. 내가 일반적으로하는 일은 작업이 수행 될 때 열리는 양식에 BackgroundWorker 구성 요소를 둔 다음 해당 인스턴스를 내 작업 클래스의 생성자에 전달하는 것입니다.

lblStatus.Text = "Initializing ..." 
bgwMain.RunWorkerAsync(someFileName) 

:

Private m_bwMain As BackgroundWorker 

Public Sub New(ByVal bwMain As BackgroundWorker) 
    m_bwMain = bwMain 

    'additional setup code here 
End Sub 

, 당신은 당신의 시작 다운로드 버튼의 클릭 이벤트 처리기에서 같은 것을 할 것입니다 작업을 시작하려면 여기

는 작업 클래스가 어떻게 보이는지이다 내 직업 클래스를 현재 폼의 private 멤버로 선언 한 다음 BackgroundWorker.DoWork 이벤트에서 인스턴스화합니다. 거기에서 파일을 다운로드하기 위해 메소드를 호출 할 수 있습니다

Private Sub bgwMain_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bgwMain.DoWork 
    m_oJobEngine = New JobEngine(CType(sender, BackgroundWorker)) 
    m_oJobEngine.DownloadFile(CStr(e.Argument)) 
End Sub 

사용자에게 진행 상황을보고하려면, 당신은 당신의 기본 폼에 클래스에 의해 제기 된 이벤트를 처리 할 수 ​​있습니다. 작업 클래스 오브젝트 선언에 WithEvents 키워드가 있는지 확인해야합니다. 이러한 핸들러에서 BackgroundWorker의 ReportProgress 메소드를 호출 할 수 있습니다. ReportProgress 내에서 UI에 필요한 모든 변경 사항을 진행 상황을 나타낼 수 있습니다. 예를 들면 다음과 같습니다.

Private Sub m_oJobEngine.DownloadProgress(ByVal bgw as Backgroundworker, ByVal bytesTransferred as Long) Handles m_oJobEngine.DownloadProgress 
    bgw.ReportProgress(0, bytesTransferred) 
End Sub 
Private Sub bgwMain_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles bgwMain.ProgressChanged 
    lblStatus.Text = CLng(e.UserState).ToString & " bytes transferred." 
End Sub 

희망이 있습니다.

0

backgroundworker가 작동해야하는 것처럼 보입니다. MSDN에 예제가 있습니다.

http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx

또는 당신이 뭔가 같이 할 수있는 :

WaitCallBack workCallBack= new WaitCallBack(DownloadMethod); 
if(!ThreadPool.QueueUserWorkItem(workCallBack, "ThreadPooled") 
{ 
    // Unable to Pool 
} 

// Work has been added to pool and will execute when possible 

어떤 당신이 스레드에 필요한 경우 어떤 매개 변수 따라 달라집니다.

+0

이벤트를 UI 스레드로 반환하는 것이 어렵 기 때문에 WaitCallback에 대한 조언을 드리겠습니다. (내가 수행하려고하는 것으로 가정합니다.) – Inferis

3

저는 다운로드 만하고 다른 비동기 처리는 필요하지 않으므로 WebClient 클래스의 비동기 메소드를 사용할 수 있습니다. 당신이 이미 자신의 수업을 가지고 있기 때문에 그것은 아마도 당신을위한 해결책이 아닙니다.

그렇지 않으면 언급 한대로 BackgroundWorker을 사용할 수 있습니다. MSDN 페이지에 예제가 나와 있습니다.

는 편집 : 짧은 이야기는 다음과 같습니다

  • 당신은 호출자의 BackgroundWorker 만들;
  • 배경 작업을 시작하려면 BackgroundWorker.RunWorkerAsync으로 전화하십시오.
  • DoWork 이벤트 처리기에서 백그라운드 작업을 수행하면 다운로드 클래스를 시작할 수 있습니다.
  • 배경 작업을 수행하는 동안 잠시 동안 CancelationPending을 확인해야합니다.
  • 진행 상황을보고하려면 백분율로 계산하고 ReportProgress으로 전화해야합니다.

정말로 맞춤 설정해야하는 항목이 있으면 언제든지 직접 Thread을 만들 수 있습니다.

저는 개인적으로 BackgroundWorker을 사용합니다. 작업의 다양한 단계에 대한 알림을 제공합니다.Thread을 사용하는 경우에는 직접 구현해야합니다.

코드가 너무 많은 인스턴스를 생성하지 않도록합니다. 동시 다운로드 수를 제한하고 해당 숫자를 지나치는 항목을 대기열에 넣고 싶습니다.

+0

Im webservices와 MTOM을 사용하여 서버에서 큰 파일을 가져 와서 WebClient와 공동 작업을 할 수 없습니다. – Stefan

+0

그런 경우 서비스 참조에서 비동기 메소드를 생성하고이를 사용합니다. – Inferis

+0

@inferis - 웹 서비스의 비동기 메소드는 진행 상황에 대한 알림을 제공하지 않습니다. –

3

UI에서 사용자에게 피드백을 제공해야하는 경우 BackgroundWorker을 강력히 권합니다. ProgressChangedRunWorkerCompleted 이벤트는 UI 스레드에서 실행되므로 마샬링을 수행 할 필요가 없으므로 코드가 복잡해질 수 있습니다.

+0

안녕하세요 @ user927258 님, 약간의 수정을 피하십시오. 참조 : http://meta.stackexchange.com/questions/180545/mass-editing-existing-answers-with-a-similar-pattern – yannis

+0

@ Inferis 괜찮습니다. – vasanth

0

clsDownload (아마도 Form 클래스)를 사용하는 클래스는 BackgroundWorker를 사용하여 다운로드 메서드를 실행해야합니다.

관련 문제