2011-05-11 3 views
0

내가 비동기 적으로 실행하는 Windows SVC를 가지고는 (내가 만드는 방법과 자신의 매개 변수를 편집 한 그들 비동기), 조금 같은 : http://msdn.microsoft.com/en-us/library/ms731177.aspxIAsyncresult - UI를 고정하지 않고 폴링합니까?

그러나, 내가 비동기 적으로 실행하려는 작업을 호출 (서비스/서버에 대한 호출)을 수행 한 다음 Backgroundworker에서 ReportProgress()를 사용하여 UI를 업데이트하십시오.이 모든 작업은 backgroundworker의 dowork() 메소드에서 발생합니다. 그러나 Endxxx 메서드를 호출하여 결과를 얻지 만 문제점은 내 코드가 아닌 것처럼 보입니까?

while (!asyncresult.IsCompleted) { // Do all UI updating etc here... } 

// Call endXXX here. 

그러나이 방법은 UI를 잠급니다. 현재 코드는 다음과 같습니다 (UI를 잠그지 않습니다) :

IAsyncResult res = null; 

       try 
       { 

        res = serviceX.BeginXXX(ResultCallBack, ""); 
       } 
       catch (FaultException<ManagementException> managementEx) 
       { 
        Logger.Error(managementEx.Detail.ToString()); 
        MessageBox.Show("Could not add printer. See log."); 
       } 



        InstallBackgoundWorker.ReportProgress(90); 
        InstallBackgoundWorker.ReportProgress(91); 
        InstallBackgoundWorker.ReportProgress(93); 

        InstallBackgoundWorker.ReportProgress(94); 
        InstallBackgoundWorker.ReportProgress(95); 
        InstallBackgoundWorker.ReportProgress(96); 
        InstallBackgoundWorker.ReportProgress(97); 



        if (res.IsCompleted) 
        { 
         ResultCallBack(res); 
        } 
        InstallBackgoundWorker.ReportProgress(100); 

이 정보가 맞습니까? 나에게 잘못된 것 같다.

+0

귀하가 주장한대로이 메시지는 Windows 서비스가 아닙니다. 그것은 WCF 서비스입니다. Windows 서비스는 Service Manager를 통해 호스트 컴퓨터에서 실행되는 응용 프로그램으로, 로그인 한 사용자가 있는지 여부에 관계없이 실행됩니다. Windows 서비스에서이 작업을 수행하는 이유에 대해 정말로 혼란 스러웠습니다. –

답변

0

제대로 비동기 패턴을 사용하고 있는지 확실하지 않습니다. 나는 개체의 서명을 모르기 때문에

void Start() 
{ 
    System.IO.Stream s = ...; 
    byte[] buf = ...; 

    // start the IO. 

    s.BeginRead(buf, 0, buf.Length, res => 
     { 
      // this gets called when it's finished, 
      // but you're in a different thread. 

      int len = s.EndRead(res); 

      // so you must call Dispatcher.Invoke 
      // to get back to the UI thread. 

      Dispatcher.Invoke((Action)delegate 
       { 
        // perform UI updates here. 
       }); 
     }, null); 

    // the IO is started (and maybe finished) here, 
    // but you probably don't need to put anything here. 
} 

Stream 작성, 그러나 희망 당신은 아이디어를 얻을 : 그것은 다음과 비슷한 모습이 될 것입니다! Begin 메서드를 호출 한 직후 이 아닌이 아닌 콜백에서 작업 완료를 처리해야합니다. IsCompleted 속성을 폴링 할 필요는 없습니다.

+0

그래서 내 코드가 BeginXXX를 호출 한 다음 EndXXX를 호출해야합니까? 나는 그것을 시도했다, 내가 만든 실수 인 것 같다. 콜백도 실행했습니다. 그래서 beginxxx와 endxxx 사이에 얼마나 많은 코드가 있겠습니까? – dotnetdev

+0

ui 업데이트의 마지막 줄과 endxxx 메서드 사이에 메서드가 완료되지 않은 경우 코드가 기다릴 것입니까? – dotnetdev

+0

BeginXXX와 EndXXX 사이에서 원하는만큼 많은 작업을 수행 할 수 있습니다. –

0

아니요. 첫 번째 방법을 사용하면 안됩니다. 비동기 방식으로 메서드를 호출하는 목적을 무효화 할 수 있습니다.

  • 진행 상황보고가 임의적이고 비현실적이기 때문에

    두 번째 접근 방식은 또한 문제가된다

  • 100 %는 작업을 알고하지 않기 때문에 심지어 100 %으로는 작업이 완료되는 것을 보장하지 않습니다 완료되었습니다.

async에서 제공하는 경우가 아니면 비동기 작업에 대한 진행률 보고서를 표시 할 방법이 없습니다.

해결 방법은 다음과 같습니다

  • 불확정 진행률 표시 줄을 표시합니다 (또한 회) 콜백

내부 결과

  • 사용자 신고 당신도 알고 있어야합니다 백그라운드 스레드에서 UI 스레드와 통신하는 문제와 Windows Forms에서 Invoke를 사용하고 WPF에서 Dispatcher를 사용하는 문제.

  • +0

    정확히 내가 생각한 것. UI를 잠그지 않고이를 수행하는 가장 좋은 방법은 무엇입니까? – dotnetdev

    +0

    예, Conrol.Invoke와 같은 문제에 대해 알고 있습니다. 불확정 진도 표시 줄을 어떻게 표시합니까? EndXXX를 호출 할 때 IsCompleted = true 인 경우 어떻게해야합니까? – dotnetdev

    +0

    글쎄, 나는 WPF에서 Progressbar.IsIndeterminate를 true로 설정할 수 있음을 안다. Windows 양식에 대한 확신이 없습니다. – Aliostad

    관련 문제