2014-04-02 155 views
0

我創建Silverlight應用程序爲CRM如下:如何強制執行停止,直到異步函數完全執行?

1- 用戶控件這是一種形式填充有使用異步從CRM檢索到的數據/等待

2-甲打印按鈕一個創建用戶控件的實例,並打印

我在執行導致打印按鈕沒有數據打印的用戶控件,意義的序列的問題,異步方法完成之前它的執行。

我的代碼如下:

用戶控制:

Public partial class ManagerContact : UserControl 
    // constructor and functions 
    ... 
    async private void getData(string contactid) 
    { 
     // get some details of the contact 

      QueryExpression query = new QueryExpression(); 
      query.EntityName = "contact"; 
      ColumnSet cset = new ColumnSet(); 
      cset.Columns = new System.Collections.ObjectModel.ObservableCollection<string>(new String[] { "emailaddress1","fullname" }); 
      query.ColumnSet = cset; 


      IOrganizationService service = SilverlightUtility.GetSoapService(); 
      var response = await service.RetrieveMultiple(query); 

      /// PROBLEM HERE 

      List<contacts> mycontactlist= new List<contacts>(); 
      // a function to fill the controls in the form with the retrieved data 
      ... 
     } 
    } 

我的打印按鈕:

private void PrintOrExport(object sender, RoutedEventArgs e) 
    { 
     PrintDocument document = new PrintDocument(); 

     ManagerContact mymanager= new Common.ManagerContact(mycontactid); 

      document.PrintPage += (s, args) => 
      { 
       // code here to prepare the pagevisual 
      } 
     document.Print("title"); 
    } 

當我點擊打印,的新實例ManagerContact用戶控件已創建且執行順利唉所有用戶控件,直到它到達線

var response = await service.RetrieveMultiple(query); 

,然後返回到打印按鈕的功能和進行打印的頁面的功能。問題是它跳過的其中I填寫表格控制與數據等的形式印有沒有數據的功能的其餘部分。

我需要找到一種方法來強制執行,以等待要返回的響應,只有它得到德響應執行將返回到主畫面的打印按鈕後剩下的。

+0

您確定要執行代碼asynchrone? – Maarten

+0

嗯,我沒有別的選擇。這是我可以將Silverlight用於CRM服務的唯一方法。 – user3340627

回答

3

你的問題是由於async void。作爲一般準則,應避免async void;它只能用於事件處理程序。欲瞭解更多信息,請參閱我的MSDN article on asynchronous best practices

所以,你getData方法應該是這樣的:

private async Task getDataAsync(string contactid) 

而且不管調用它應該await返回,這意味着功能也需要async並返回TaskTask<T>等方面的Task

最終,你會發現你的構造函數不能是async,所以我建議你創建一個異步工廠方法as I describe on my blog

class ManagerContact 
{ 
    private ManagerContact(int contactId) 
    { 
    ... 
    } 

    private async Task InitializeAsync() 
    { 
    await getDataAsync(); 
    ... 
    } 

    public static async Task<ManagerContact> CreateAsync(int id) 
    { 
    var result = new ManagerContact(id); 
    await result.InitializeAsync(); 
    return result; 
    } 
} 

然後你就可以使用這樣的:

private async void PrintOrExport(object sender, RoutedEventArgs e) 
{ 
    ManagerContact mymanager = await Common.ManagerContact.CreateAsync(mycontactid); 
    ... 
} 
+0

這就是我正在尋找的。非常感謝 :) – user3340627