2014-02-19 32 views
0

我有一個類庫https://github.com/trydis/FIFA-Ultimate-Team-2014-Toolkit我想爲它做一個包裝,而不是僅僅調用FutClient我想創建一個FutClientWrapper,我可以處理異常,重新登錄和登錄我想要包裝的接口是https://github.com/trydis/FIFA-Ultimate-Team-2014-Toolkit/blob/master/UltimateTeam.Toolkit/IFutClient.cs爲異步庫創建泛型包裝問題

所以我做了http://pastebin.com/0EJdCbbr

代碼片斷

public async Task<AuctionResponse> SearchAsync(SearchParameters searchParameters) 
    { 
     return await Invoke(f => f.SearchAsync(searchParameters), searchParameters); 
    } 

    public async Task<AuctionResponse> PlaceBidAsync(AuctionInfo auctionInfo, uint bidAmount = 0) 
    { 
     return await Invoke(f => f.PlaceBidAsync(auctionInfo, bidAmount), auctionInfo); 
    } 

    public async Task<Item> GetItemAsync(long resourceId) 
    { 
     return await Invoke(f => f.GetItemAsync(resourceId), resourceId); 
    } 

    public TResult Invoke<TResult>(Func<FutClient, TResult> func, object requestDetails = null, 
     [CallerMemberName] string exceptionMessage = null) 
    { 
     try 
     { 
      if (LastException + new TimeSpan(0, 0, 30) < DateTime.Now) 
      { 
       TResult result = func(_futClient); 
       return result; 
      } 
     } 
     catch (Exception e) 
     { 

在這裏,我嘗試來包裝,趕上Futclient內拋出的任何異常,而是我GE TA空例外,例如該行

return await Invoke(f => f.GetItemAsync(resourceId), resourceId); 

而且似乎它的,因爲我的

TResult result = func(_futClient); 
       return result; 

不會運行異步,它只是返回一個空應答(所有空值)

所以我改變了它看起來像http://pastebin.com/pJkPr2xN

代碼片段:

public async Task<AuctionResponse> GetTradePileAsync() 
    { 
     return await NewInvoke<AuctionResponse>(new Task<object>(() => _futClient.GetTradePileAsync())); 
    } 

    public async Task<WatchlistResponse> GetWatchlistAsync() 
    { 
     return await NewInvoke<WatchlistResponse>(new Task<object>(() => _futClient.GetWatchlistAsync())); 
    } 

    public async Task<TResult> NewInvoke<TResult>(Task<object> taskToRun) where TResult : class 
    { 
     try 
     { 
      taskToRun.Start(); 
      Task.WaitAll(taskToRun); 
      return taskToRun.Result as TResult; 
     } 
     catch (AggregateException ex) 
     { 
      //ex.InnerException 
      return null; 
     } 
     catch (Exception e) 
     { 
      return null; 

     } 
    } 

而且在這裏我得到我的invoke方法之外的異常

所以,我應該怎麼做這個所以它可以同時處理任務和任務爲響應類型和需要的參數

X號和它應該再拋Invoke方法內的任何異常,所以我只有一個地方需要捕獲異常

回答

1

您必須在返回之前在try塊內部await,否則異常將不會被catch。你的第一次嘗試實際上更接近正確的做法。

public async Task<TResult> Invoke<TResult>(Func<FutClient, Task<TResult>> func, object requestDetails = null, 
    [CallerMemberName] string exceptionMessage = null) 
{ 
    try 
    { 
     if (LastException + new TimeSpan(0, 0, 30) < DateTime.Now) 
     { 
      TResult result = await func(_futClient).ConfigureAwait(false); //Here we both await for the result and set `ConfigureAwait` to false so we don't need to waist extra time trying to marshal back on to the original Synchronization context as we have no need for it for the rest of the method. 
      return result; 
     } 
    } 
    catch (Exception e) 
    { 
     //... 

然後你只需要使用它像下面

public Task<AuctionResponse> PlaceBidAsync(AuctionInfo auctionInfo, uint bidAmount = 0) 
{ 
    return Invoke(f => f.PlaceBidAsync(auctionInfo, bidAmount), auctionInfo); 
} 

沒有必要await在這外功能,你可以直接返回由Invoke

+0

返回的任務有沒有ConfigureAwait在功能上,我需要設置一些東西,然後才能打電話給我? – Mech0z

+0

如果我在哪裏TResult:任務我得到不能隱式轉換類型'無效'到'TResult' – Mech0z

+0

Nwm沒有看到你把任務在方法簽名,現在它不能處理方法與returntype任務雖然 – Mech0z