2012-05-20 3 views
-2

이 하나가 저를 곤혹스럽게합니다. 엔터프라이즈 용 소프트웨어 설치를 돕기 위해 만든 간단한 유틸리티가 있습니다.C# BackgroundWorker_DoWork는 일부 작업 만 수행합니다.

private void backupButton_Click(object sender, EventArgs e) 
{ 
    backgroundBackup.RunWorkerAsync(); 
} 


private void backgroundBackup_DoWork(object sender, DoWorkEventArgs e) 
{ 
    ... 
} 

private static void CopyAll(DirectoryInfo source, DirectoryInfo target) 
{ 
    ... 
} 

// I removed the message boxes from DoWork, and added a RunWorkerCompleted event, 
// but neither the confirmation nor the error messgae box from RunWorkerCompleted are shown. 

private void backgroundBackup_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    ... 
} 

이 작동하지만, 예상되는 결과를 생성하지 않습니다 : 하나 개의 구성 요소의 AppData 현재 사용자가 파일을 자신의 컴퓨터에 가지고 있으며, 바탕 화면에 폴더에 저장합니다 백업합니다. 각 사용자가 백업하는 전체 파일 크기가 GB 또는 2에 가까워지기 때문에이 작업을 백그라운드 스레드에 넣었습니다. 이 작업을 실행할 때마다 대상의 일부 파일 및 폴더가 대상에 복사되지만 일부는 복사 될 때마다 달라집니다. 때로는 소수의 파일과 폴더 만 복사되는 경우가 있습니다. 거의 모든 것이 모두 복사되지만 전체 대상은 복사되지 않습니다. 이 작업을 간단한 콘솔 앱에 배치하면 매번 작동합니다. DoWork 메서드에서 모든 작업을 수행하지 못하게하는 BackgroundWorker 클래스에 대해 알아야 할 사항이 있습니까?

편집 :

나는 내가 BackgroundWorker 구성 클래스 문제를 복잡하게 걸쳐있을 수 있습니다 생각합니다. 나는 동료에게 말씀, 그들은 잠재적으로 긴 과정 처리하기 위해 새 스레드를 만드는 간단한 방법 제안 : 이것은 나를 위해 수행 할 작업이 도착

private void backupButton_Click(object sender, EventArgs e) 
    { 
     Thread backupThread = new Thread(backupThreadJob); 
     backupThread.Start();  
    } 

    private void backupThreadJob() 
    { 
     try 
     { 
      //copy files and stuff 
     } 

     catch(Exception ex) 
     { 
      MessageBox.Show("Error: " + ex.Message); 
     } 
    } 

; BackgroundWorker를 사용하려는 시도에서 실패했고 일부 파일 만 복사되는 이유를 알 수 없었습니다. 모두의 도움에 감사드립니다!

+0

몇 가지 예외가 제기되고 있지만 백그라운드 스레드에서 호출하고 기본 UI 스레드가 아니라기 때문에 메시지 상자가 표시되지 않습니다.UI 스레드에서 이러한 메서드를 호출해야합니다. –

+1

나는 UI 스레드가 아니기 때문에 예외가 있으며 메시지 상자가 표시되지 않을 것으로 예상됩니다. 대신 예외를 기록하려고 시도하고 일반적으로 모든 예외를 사용하지 마십시오. 그것은 아마도 지금까지 깨달은 것처럼 디버깅을 악몽처럼 만듭니다. –

+0

catch 블록에있는 MessageBox를 본 적이 있습니까? 백그라운드 스레드에서 하드 코딩 된 예외를 throw하여 메시지 상자가 표시되는지 확인하십시오. 내 생각 엔 당신의 프로세스가 오류를 던지고있는 것 같습니다. –

답변

4

이것은 완전한 대답이 아닙니다. 하지만 다음과 같은 문제와 함께 할 수있는 뭔가가 있다고 상상할 수 :

BackgroundWorker 다른에 DoWork 메소드를 실행 기억을, 비 UI 스레드, 그래서 거기 MessageBox.Show를 호출하는 것은 좋은 생각이 아니다.

당신은 당신의 DoWork 이벤트 처리기에서 사용자 인터페이스 객체를 조작하지 않도록주의해야합니다 : 당신은 UI ("전경")에서 실행중인 경우에만 스레드 UI 물건을 수행해야합니다. 대신 ProgressChanged 및 RunWorkerCompleted 이벤트를 통해 사용자 인터페이스에 통신하십시오.MSDN reference page for the BackgroundWorker class

나는 예외가 당신의 방법에 어딘가에 발생하고 catch 블록의 메시지 상자를 표시 할 경우,이 호출이 처리되지 않는 또 다른 예외를 트리거 상상할 수있다. .. 그리고 따라서 당신의 방법은 조기에 중단됩니다.

+0

답장을 보내 주셔서 감사합니다. DoWork에서 메시지 상자를 제거하고 RunWorkerCompleted 이벤트를 추가했지만 RunWorkerCompleted의 확인이나 오류 메시지 상자는 표시되지 않습니다. –

+0

링크 된 MSDN 참조 시트의 첫 번째 예제 코드에서 DoWork 완료시 RunWorkerCompleted가 자동으로 호출된다는 잘못된 가정이 있습니까? –

+0

내 실수, 오랜 독자, 처음 포스터 ... –

1

다음은 백그라운드 스레드에서 메시지 상자를 호출 할 수 있음을 보여주는 예입니다. MessageBox.Show는 정적 메서드 호출이며 백 그라운드 스레드에서 호출 할 수 있습니다. UI 레이어의 아무 것도 액세스하려고 시도해서는 안됩니다 (바인딩 된 백업 객체 포함 - WPF는 여기 있다고 생각하십시오).

여기가 메시지 상자에 사용되는 예입니다.

10 개의 파일을 복사하고 백그라운드에서 복사 프로세스를 시작합니다. 오류가 발생하고 (파일이 존재하는 등) 사용자에게 덮어 쓰기를 요청하라는 메시지가 표시되면 사용자로부터 확인을 요청하는 메시지 상자를 표시 할 수 있습니다.

private void button1_Click(object sender, EventArgs e) 
{ 
    BackgroundWorker bw = new BackgroundWorker(); 
    bw.RunWorkerCompleted += BwOnRunWorkerCompleted; 
    bw.DoWork += BwOnDoWork; 
    bw.RunWorkerAsync(); 
} 

private void BwOnDoWork(object sender, DoWorkEventArgs doWorkEventArgs) 
{ 
    MessageBox.Show("This is a message from a background thread"); 
} 

private void BwOnRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs runWorkerCompletedEventArgs) 
{ 
    MessageBox.Show("Your done"); 
} 
관련 문제