2010-11-10 74 views
0

我正在開發與vsNET 2010和C#窗體窗體的Windows應用程序。這個應用程序有一個查詢服務的用戶控件(WCF託管在win服務上),並且需要在不阻止UI的情況下執行此操作。用戶控件包含一個將顯示結果的網格。我認爲我的情況最爲常見。我對你的問題是用C#可以做些什麼,以使下面的代碼運行更平滑,並具有更好的錯誤處理。我正在使用MehtodInvoker,因此我可以避免爲此調用寫入兩個分離方法 - 等待 - 填充方案。異步調用最佳實踐

public void LoadData() 
{ 
    StartWaitProgress(0); 
    ThreadPool.QueueUserWorkItem(x => 
    { 
     try 
     { 
      MyDocMail[] mails; 
      var history = Program.NoxProxy.GetDocumentHistory(out mails, Program.MySessionId, docId); 
      this.Invoke(new MethodInvoker(delegate() 
      { 
       this.SuspendLayout(); 
       gridVersions.Rows.Clear(); 
       foreach (var item in history) 
       { 
        gridVersions.Rows.Add(); 
        int RowIndex = gridVersions.RowCount - 1; 
        DataGridViewRow demoRow = gridVersions.Rows[RowIndex]; 
        demoRow.Tag = item.Id; 
        if (gridVersions.RowCount == 1) 
        { 
         demoRow.Cells[0].Value = Properties.Resources.Document_16; 
        } 
        demoRow.Cells[1].Value = item.Title; 
        demoRow.Cells[2].Value = item.Size.GetFileSize(); 
        demoRow.Cells[3].Value = item.LastModified; 
        demoRow.Cells[4].Value = item.CheckoutBy; 
        demoRow.Cells[5].Value = item.Cotegory; 
       } 
       gridEmails.Rows.Clear(); 
       foreach (var item in mails) 
       { 
        gridEmails.Rows.Add(); 
        int RowIndex = gridEmails.RowCount - 1; 
        DataGridViewRow demoRow = gridEmails.Rows[RowIndex]; 
        demoRow.Tag = item.Id; 
        demoRow.Cells[1].Value = item.From; 
        demoRow.Cells[2].Value = item.To; 
        demoRow.Cells[3].Value = item.Date; 
       } 
       this.ResumeLayout(); 
      })); 
     } 
     catch (Exception ex) 
     { 
      Program.PopError(ex); 
      this.Invoke(new MethodInvoker(delegate() { this.Close(); })); 
     } 
     finally { this.Invoke(new MethodInvoker(delegate() { StopWaitProgress(); })); } 
    }); 
} 

回答

3

有什麼不對您的解決方案的,但可以用BackgroundWorker更輕鬆地完成它。

BackgroundWorker處理線程異常,在WPF窗口調用Invoke,並幫助進度報告和取消。更多例子here

P.S.未來的C#版本可能會更容易 - 請查看Async CTP

+0

你也可以使用.NET 4框架中的任務來清理它。 – 2010-11-10 04:37:35

+0

我已經在C#2.0中嘗試過BackgroundWorker解決方案,但我沒有看到任何優勢,我使用BackgroundWorker將代碼分離到多個方法/事件中。在我的應用程序中,有些情況下,我可以在10次調用wcf服務的同一窗體中進行操作。爲了加速這個調用,我必須讓它們在同一時間(在ThreadPool上並行運行),以便產生BackgroundWorker的10個實例...上面的代碼更加緊湊,因爲我可以爲每個異步調用。 – 2010-11-10 09:12:55

+1

請記住,您可以以編程方式實例化BackgroundWorker,並使用匿名方法或lambda表達式來處理事件(這通常是我所做的)。最好的解決方案取決於你的最終目標。你能詳細說明你的意思是「更平滑,更好的錯誤處理」嗎? – 2010-11-10 10:53:07