2014-01-23 2 views
0

간단한 winforms C# 응용 프로그램을 개발하고 있습니다. 다른 배경 작업자가 내 WCF 서버에 문의하는 동안 상단에로드 양식을 표시하려면 백그라운드 작업자를 사용하고 싶습니다.배경 작업자 의문점

내 WinForms 앱은 다음과 같이 작동합니다. 메인 폼과 많은 UserControls가 있습니다. 앱을 시작하면 LoginUserControl을 MainForm 컨트롤에 추가합니다. LoginUserControl에서 "Login Button"을 클릭하면 Loading Form을 표시하고 동시에 서버에 문의하려고합니다. 나중에 Loading Background Worker에 서버 컨설턴트 백그라운드 워커가 완료되었음을 나타내는 신호를 보내야합니다.

제 질문은 로딩 패널이 필요한 각 UserControl에 2 명의 백그라운드 워커를 구현해야합니까? 배경 근로자 간의 의사 소통을 구현하는 방법은 무엇입니까?

+0

이렇게하면 도움이 될 것입니다 - 비슷한 종류의 (스플래시 화면) http://stackoverflow.com/questions/7955663/how-to-build-splash-screen-in-windows-forms-application – owen79

+0

가능하면' I/O 바운드 작업을 처리 할 때'BackgroundWorker' 대신에'async'와'await'을 사용합니다. –

+0

두 개의 BackgroundWorker가 필요한 이유는 무엇입니까? 맨 위 양식을 표시하고 배경 작업자 한 명에게 전화를하고 마지막으로 완료된 이벤트는 양식을 제거합니다. – Paparazzi

답변

0

우선 BackgroundWorker에서 Form을 시작하는 것은 좋지 않은 아이디어입니다. 이는 Windows Forms에있는 단일 UI 스레드와 충돌합니다.

UI 스레드에서 Form을 열고 BackgroundWorker에서 Invoke을 호출하여 양식을 닫는 것이 좋습니다.

form.Invoke((MethodInvoker)delegate() 
{ 
    busyForm.Close(); 
}); 
1

나중에, 나는로드 배경 작업자에 서버상의 배경 작업자가 완료되었음을 나타내는 신호를 보내야합니다.

아니요, 필요하지 않습니다.

백그라운드 작업자는 정확히 말하면 백그라운드에서 작업을 수행하는 "작업자"입니다. 귀하의 경우에있는 작업은 보유하고있는 WCF 서비스와 통신하는 방법입니다. 작업이 완료되면 작업자가 종료됩니다 (또는 예외가 throw됩니다).

  • 작업자를 시작 (양식 모달 경우 먼저해야합니다)
  • 양식
에게 숨길
  • 가 노동자를 수신 형태를 RunWorkerCompleted 이벤트를보기 다음과 같이 그래서 사건의 순서는

    실제로 서버와 통신하지 않는 양식 (실제로는 중요하지 않음)을 작성했으며 간단한 진행률 표시 줄을 보여줍니다.

    • workerControl 서브 클래스, 그래서 양식 편집기를 통해 추가 :
      public partial class FastForwardForm : Form 
      { 
          private Exception asyncError; 
      
          public event DoWorkEventHandler DoWork 
          { 
           add { worker.DoWork += value; } 
           remove { worker.DoWork -= value; } 
          } 
      
          public FastForwardForm() 
          { 
           InitializeComponent(); 
          } 
      
          public Exception AsyncError 
          { 
           get { return asyncError; } 
          } 
      
          private void FastForwardForm_Shown(object sender, EventArgs e) 
          { 
           worker.RunWorkerAsync(); 
          } 
      
          private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e) 
          { 
           progressBar.Value = e.ProgressPercentage; 
           statusLabel.Text = e.UserState.ToString(); 
          } 
      
          private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
          { 
           if (e.Error != null) asyncError = e.Error; 
           HideProgressForm(); 
           worker.Dispose(); 
          } 
      
          private void HideProgressForm() 
          { 
           //not actually needed, the callback runs on the UI thread. 
           if (InvokeRequired) 
           { 
            Invoke((Action)HideProgressForm); 
            return; 
           } 
           Close(); 
          } 
      } 
      

      는 다음 사항에 유의하시기 바랍니다. 즉, 해당 콜백은 UI 스레드에서 실행되며 에 내가 추가 한 if (InvokeRequired) 부분이 필요하지 않음을 의미합니다. 이유가 무엇인지 물어 보지 말고, 리팩토링 후 놓쳤습니다.
    • 이 양식은 사용자에게 더러운 작업을합니다. 표시된대로 즉시 작업을 시작하십시오. 프로세스의 예외를 저장합니다. DoWork을 노출하여 양식 외부의 배경 작업을 추가 할 수 있습니다.
    • 코드가 완벽하지 않습니다. 양식을 다시 사용해야하는 경우 worker.Dispose();을 제거하고 양식 Dispose() 메소드에 추가해야합니다.

    이제 "대기중인"애니메이션을 양식에 표시해야하는 경우 다른 작업자가 필요하지 않습니다. 애니메이션을 새로 고치려면 Timer 컨트롤이 필요하지만 그 또 다른 이야기입니다.