2011-05-11 44 views
0

我有這是異步運行Windows SVC(我編輯的方法和參數,使它們異步),有點像:http://msdn.microsoft.com/en-us/library/ms731177.aspxIAsyncresult - 不凍結UI的輪詢?

不過,我打電話,我要異步運行的任務(調用服務/服務器),然後更新UI(使用BackgroundWorker上的ReportProgress() - 所有這些都發生在背景工作者的dowork()方法中)。但是,我調用Endxxx方法來獲得結果,但問題是,我的代碼不應該是這樣嗎?

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

// Call endXXX here. 

但是,這種方法會鎖定用戶界面。目前,我的代碼是這樣的(並且不鎖定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服務是一個應用程序,通過服務管理器在主機上運行,​​並且無論用戶是否登錄都可以運行。您讓我非常困惑,因爲您爲什麼在Windows服務中這樣做。 – 2011-05-11 23:05:43

回答

0

我不確定您是否正確使用異步模式。它應該是這個樣子:寫有Stream

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. 
} 

,因爲我不知道你的對象的簽名,但希望你的想法!在您調用Begin方法後,您需要直接在您提供的回調中完成操作,即而不是。您不應該輪詢IsCompleted屬性。

+0

所以我的代碼應該調用BeginXXX,然後EndXXX?我嘗試過,看起來像我犯的錯誤。它也執行回調。那麼beginxxx和endxxx之間有多少代碼並不重要? – dotnetdev 2011-05-11 23:32:36

+0

我猜如果在ui更新的最後一行和endxxx方法之後,如果方法沒有完成,代碼將會等待? – dotnetdev 2011-05-11 23:39:36

+0

你可以在BeginXXX和EndXXX之間做很多其他的事情。 – 2011-05-11 23:54:26

0

不,你不應該採取第一種方法,因爲它違背了以異步方式調用方法的目標。

第二種方法也比較麻煩,因爲

  • 進度報告是任意的,不現實的
  • 即使有100%它並不能保證工作完成,因爲在100%它不知道,如果作品已經完成。

沒有辦法顯示異步作業的進度報告,除非異步提供它。

解決辦法是:

  • 顯示的不確定進度條(也叫微調)結果回調

  • 報告用戶還必須瞭解從後臺線程與UI線程通信的問題以及在Windows窗體中使用Invoke並在WPF中使用分派器的問題。

  • +0

    正是我的想法。那麼在不鎖定用戶界面的情況下做到這一點的最佳方式是什麼? – dotnetdev 2011-05-11 23:03:09

    +0

    是的,我知道像使用Conrol.Invoke的問題。如何顯示不確定的進度欄?當我打電話給EndXXX時,只有當IsCompleted = true時我該如何做? – dotnetdev 2011-05-11 23:12:33

    +0

    那麼,我知道在WPF中,您可以將Progressbar.IsIndeterminate設置爲true。不確定Windows窗體。 – Aliostad 2011-05-11 23:14:49