2015-07-22 71 views
0

想要更新C#Winforms應用程序以使用await。 應用程序通過SDK調用MYOB Accountright API。 我使用點NET框架4.5.1重構api調用以等待使用

舊的代碼是這樣的

public void GetItems( CompanyFile companyFile) 
     { 
      var itemSvc = new ItemService(MyConfiguration, null, MyOAuthKeyService); 
      string pageFilter = string.Format("$top={0}&$skip={1}&$orderby=Date desc", PageSize, 
               PageSize * (_currentPage - 1)); 
      itemSvc.GetRange(MyCompanyFile, pageFilter, MyCredentials, OnComplete, OnError); 
     } 

     /// <summary> 
     /// Method called on Async complete 
     /// </summary> 
     /// <param name="statusCode"></param> 
     /// <param name="items"></param> 
     /// <remarks></remarks> 
     private void OnComplete(System.Net.HttpStatusCode statusCode, 
           PagedCollection<Item> items) 
     { 
      myItems = items; 
     } 

    /// <summary> 
    /// Callback if there is an error 
    /// </summary> 
    /// <param name="uri"></param> 
    /// <param name="ex"></param> 
    /// <remarks></remarks> 
    private void OnError(Uri uri, Exception ex) 
    { 
     Trace.WriteLine("In OnError"); 

     MessageBox.Show(ex.Message); 
    } 

我想要的代碼是這樣的

private async Task FetchItemsAsync() 
{ 
     var itemSvc = new ItemService(MyConfiguration, null, MyOAuthKeyService); 

     string pageFilter = string.Format("$top={0}&$skip={1}&$orderby=Date desc", PageSize, 
              PageSize * (_currentPage - 1)); 

     itemSvc.GetRange(MyCompanyFile, pageFilter, MyCredentials, OnComplete, OnError); 

     var totalPages = (int)Math.Ceiling((double)(myItems.Count/PageSize)); 

     while (_currentPage < totalPages) 
     { 
      await LoadMore(); // how do I write this? 
     } 
} 

我該怎麼辦呢?

[Update5]

我試圖

private const double PageSize = 400; 
    protected CancellationTokenSource MyCancellationTokenSource; 
    protected CompanyFile MyCompanyFile; 
    protected IApiConfiguration MyConfiguration; 
    protected ICompanyFileCredentials MyCredentials; 

    protected ItemService MyItemService; 
    protected IOAuthKeyService MyOAuthKeyService; 

    private int _currentPage = 1; 
    private int _totalPages; 

    public void FetchItems(CompanyFile companyFile, IApiConfiguration configuration, ICompanyFileCredentials credentials) 
    { 
     MyCompanyFile = companyFile; 
     MyConfiguration = configuration; 
     MyCredentials = credentials; 
     MyCancellationTokenSource = new CancellationTokenSource(); 
     MyItemService = new ItemService(MyConfiguration, null, MyOAuthKeyService); 
     FetchAllItemsAsync(); 
    } 

    private async void FetchAllItemsAsync() 
    { 
     try 
     { 
      var items = new List<Item>(); 
      int totalPages = 0; 
      do 
      { 
       string pageFilter = string.Format("$top={0}&$skip={1}&$orderby=Date desc", PageSize, PageSize * (_currentPage - 1)); 
       CancellationToken ct = MyCancellationTokenSource.Token; 
       Log("About to Await GetRange"); 

       Task<PagedCollection<Item>> tpc = MyItemService.GetRangeAsync(MyCompanyFile, pageFilter, MyCredentials, ct, null); 
       Log("About to Await GetRange B"); 

       PagedCollection<Item> newItems = await tpc; // fails here 

       Log("Page {0} retrieved {1} items", _currentPage, newItems.Count); 
       if (totalPages == 0) 
       { 
        totalPages = (int)Math.Ceiling((items.Count/PageSize)); 
       } 
       items.AddRange(newItems.Items.ToArray()); 
       _currentPage++; 
      } 
      while (_currentPage < totalPages); 
      MessageBox.Show(string.Format("Fetched {0} items", items.Count)); 
     } 
     catch (ApiCommunicationException ex) 
     { 
      Log(ex.ToString()); 
      throw; 
     } 
     catch (Exception exception) 
     { 
      Log(exception.ToString()); 
      throw; 
     } 
    } 

不過,我得到一個ValidationException

{"Encountered a validation error (http://localhost:8080/AccountRight/ab5c1f96-7663-4052-8360-81004cfe8598/Inventory/Item/?$top=400&$skip=0&$orderby=Date desc)"} 
    [MYOB.AccountRight.SDK.ApiValidationException]: {"Encountered a validation error (http://localhost:8080/AccountRight/ab5c1f96-7663-4052-8360-81004cfe8598/Inventory/Item/?$top=400&$skip=0&$orderby=Date desc)"} 
    base: {"Encountered a validation error (http://localhost:8080/AccountRight/ab5c1f96-7663-4052-8360-81004cfe8598/Inventory/Item/?$top=400&$skip=0&$orderby=Date desc)"} 
    ErrorInformation: "Warning, error messages have not been finalised in this release and may change" 
    Errors: Count = 1 
    RequestId: "e573dfed-ec68-4aff-ac5e-3ffde1c2f943" 
    StatusCode: BadRequest 
    URI: {http://localhost:8080/AccountRight/ab5c1f96-7663-4052-8360-81004cfe8598/Inventory/Item/?$top=400&$skip=0&$orderby=Date desc} 

我交張貼了這個問題 MYOB Support

回答

3

的最新版本的MYOB.AccountRight.API.SDK你引用已經overloads支持異步上.NET4,.NET45和PCL /等待。

Sample code被創建爲一個使用.NET 3.5(因此沒有異步/等待)的人的例子。另一個樣品(windows phone)顯示異步/地等待着action using the SDK

[更新]

你可能會得到一個OData的相關的異常爲Item實體不具有Date場,而您可以通過過濾(見docs) 。

當您捕獲一個ApiCommunicationException(其中ApiValidationException是一個子類)時,有一個Errors屬性提供更多詳細信息。

還有一個RequestId(以及其他一些屬性),如果您在與雲託管API交談時遇到問題,您需要與支持人員交談,這非常有用。

+1

僅供參考:目前我們正在準備一個新版本(候選)與更新nuget引用其中應在未來幾天內提供。 –

+0

你有沒有關於如何調用ItemService.GetAsync的例子? –

+1

不與ItemService,但這是與[ContactService](https://github.com/MYOB-Technology/AccountRight_WindowsMo​​bile_sampleApp/search?utf8=%E2%9C%93&q=GetAsync)之一 - 語法是相同的。事後看來,我現在可能會稍微寫一點,但如果你知道異步/等待,這應該是一件輕而易舉的事情。 –

1

可以使用TaskCompletionSource反對你可以用結果或錯誤回調來解決。我不確定錯誤回調的簽名是什麼,所以部分可能不會工作。

private Task<PagedCollection<Item>> FetchItemsAsync() 
{ 
    var taskSource = new TaskCompletionSource<PagedCollection<Item>>(); 

    var itemSvc = new ItemService(MyConfiguration, null, MyOAuthKeyService); 
    string pageFilter = string.Format("$top={0}&$skip={1}&$orderby=Date desc", PageSize, 
               PageSize * (_currentPage - 1)); 
    itemSvc.GetRange(
     MyCompanyFile, 
     pageFilter, 
     MyCredentials, 
     (statusCode, items) => taskSource.TrySetResult(items), 
     (error) => taskSource => taskSource.TrySetException(error) // Not sure if this is correct signature 
     ); 
    return taskSource.Task; 
} 

然後,您可以返回它創建的Task對象,您可以將它用於異步事件。我並不確定你想要實現什麼邏輯,因爲你的問題不是很詳細,但是你可以用await命令來使用這個方法,因爲它返回一個如下所示的Task對象。

private async void FetchAllItemsAsync() 
{ 
    int totalPages; 
    do 
    { 
     items = await FetchItemsAsync() 
     totalPages = (int)Math.Ceiling((double)(items.Count/PageSize)); 
     _currentPage++; 
    } while (_currentPage < totalPages) 

} 
+0

謝謝你,只是測試....我添加了錯誤代碼 –

+0

我更新了我的問題與我的實現你的想法。但是,我收到了錯誤的請求錯誤 –

+0

服務器返回了該異常。你能看看異常信息,看看服務器說你的請求有問題嗎? –