2015-07-22 66 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

服务器返回了该异常。你能看看异常信息,看看服务器说你的请求有问题吗? –