2010-05-17 23 views
1

從我的WPF應用程序調用Web服務時遇到了很大的問題。應用程序/窗口鎖定,直到過程完成。我試圖異步運行,但問題仍然存在。當調用webservice時,WPF窗口被鎖定。即使在異步運行時

目前,我所做的Web服務調用可以持續45-60秒。它在服務器上運行一個進程來獲取大量數據。由於需要一段時間,我希望有一個進度條不斷移動,以便用戶看到應用程序沒有停滯或任何事情(您知道他們有多不耐煩)。

所以:

private void btnSelect_Click(object sender, RoutedEventArgs e) 
    { 
     wDrawingList = new WindowDrawingList(systemManager); 

     AsyncMethodHandler caller = default(AsyncMethodHandler); 

     caller = new AsyncMethodHandler(setupDrawingList); 

     // open new thread with callback method 
     caller.BeginInvoke((Guid)((Button)sender).Tag, MyAsyncCallback, null); 
    } 

點擊一個按鈕,該應用程序將創建形式異步的東西將被張貼到,併成立了異步調用的東西的異步方法。

public bool setupDrawingList(Guid ID) 
    { 
     if (systemManager.set(ID)) 
     { 
      wDrawingList.Dispatcher.Invoke(DispatcherPriority.Background, new Action(() => 
      { 
       wDrawingList.ShowForm(); 
       Hide(); 
      })); 

      return true; 
     } 

     return false; 
    } 

這是異步方法。 showForm方法包含設置新表單的呼叫,包括怪物網絡服務呼叫

public void MyAsyncCallback(IAsyncResult ar) 
    { 
     // Because you passed your original delegate in the asyncState parameter of the Begin call, you can get it back here to complete the call. 
     MethodDelegate dlgt = (MethodDelegate)ar.AsyncState; 

     // Complete the call. 
     bool output = dlgt.EndInvoke(ar); 

     try 
     { 
      // Retrieve the delegate. 
      AsyncResult result = (AsyncResult)ar; 
      AsyncMethodHandler caller = (AsyncMethodHandler)result.AsyncDelegate; 

      // Because this method is running from secondary thread it can never access ui objects because they are created 
      // on the primary thread. 

      // Call EndInvoke to retrieve the results. 
      bool returnValue = caller.EndInvoke(ar); 

      // Still on secondary thread, must update ui on primary thread 
      UpdateUI(returnValue == true ? "Success" : "Failed"); 
     } 
     catch (Exception ex) 
     { 
      string exMessage = null; 
      exMessage = "Error: " + ex.Message; 
      UpdateUI(exMessage); 
     } 
    } 

    public void UpdateUI(string outputValue) 
    { 
     // Get back to primary thread to update ui 
     UpdateUIHandler uiHandler = new UpdateUIHandler(UpdateUIIndicators); 
     string results = outputValue; 

     // Run new thread off Dispatched (primary thread) 
     this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, uiHandler, results); 
    } 

    public void UpdateUIIndicators(string outputValue) 
    { 
     // update user interface controls from primary UI thread 
     sbi3.Content = "Processing Completed."; 
    } 

任何幫助或理論的讚賞。我很茫然。

在此先感謝

回答

1

您正在使用調度程序調用GUI方法。這意味着即使您開始使用後臺線程,您也會直接切換回GUI線程,因此GUI將無法響應。

您需要讓主要工作發生在後臺線程上,然後在需要更新進度欄時僅使用調度程序切換到GUI線程。

0

我居然回答我的問題,因爲我寫的,但我認爲是我寫的我可能也有萬一有人回答人需要它一起發佈。

我意識到引起問題的方法是在基本覆蓋主線程的調度程序中,所以即使我設置了一個很好的異步線程,我仍然返回並運行主要的進程,線。

或者至少這是我的解釋,任何進一步的意見,以幫助我進一步理解是被推崇。

因此,我從ShowForm方法中刪除了怪物調用,並將其直接放入異步方法和BooYah!窗口功能是我的。

HTH

+0

原來你解決得比我輸入的速度快。好一個。 – 2010-05-17 13:06:30

0

看起來你正在從你的異步方法(wat?)同步做UI的東西。此外,您的代碼過於複雜,您可能會注意到,因爲您已經自行處理它。

我建議大幅簡化這個,主要是通過JUST異步執行Web服務調用,然後從回調中更新UI。一旦你有這個工作,你可以看到關於加入所有這些讓我的大腦受傷的其他東西。

+0

同意。我確實需要把它整理一下。這只是幾個小時的黑客攻擊和嘗試不同的事情的結果,大聲笑 – SumGuy 2010-05-17 15:09:45

+0

@SumGuy雅,之前完成。現在,我製作了一個測試應用程序,它可以完成我需要的功能,以便驗證代碼,然後將其展開。比起嘗試使用已有代碼的新代碼更好,當我迷失方向時... – Will 2010-05-17 15:34:55

相關問題