2014-10-19 50 views
0

所以我在我的基本控制器這種方法:殉異步/ await方法調用

protected async Task<KeyValuePair<bool, string>> ExecuteSimpleQuery(Func<Task<bool>> service) 
{ 
    var success = false; 
    var message = string.Empty; 

    try 
    { 
     success = await service.Invoke(); 
    } 
    catch (Exception exception) 
    { 
     message = exception.Message; 
     success = false; 
    } 

    return new KeyValuePair<bool, string>(success, message); 
} 

我想用這樣的:

public async Task<ActionResult> Login(RegisterDto register) 
{ 
    var objectStore = 
     await this.ExecuteSimpleQuery(async() => await this.securityService.LoginAsync(register.UserName, register.Password, true)); 

    if (objectStore.Key) 
    { 
     return this.RedirectToAction("Index", "Toolbox"); 
    } 

    this.TempData["error"] = objectStore.Value; 
    return this.View(register); 
} 

我路過那麼通過對ExecuteSimpleQueryawaitable方法LoginAsync,我只是想確保我正在等待該方法。

我的思維過程是:

  1. LoginAsync返回Task<bool>因此Func不得不返回。
  2. 當它通過它時,你可以await它,所以呢。
  3. 因爲Func回報Task<bool>ExecuteSimpleQuery可以await它在那裏,所以應該
  4. ExecuteSimpleQuery正在等待的方法,因此必須具有async關鍵字,因此必須返回Task<T>
  5. 最後一點傳播到Login動作,該方法返回Task<T>,因此它可以等待,所以應該。

我是否關閉?

+0

爲什麼這麼複雜?你是誰將登錄調用委託給'ExecuteSimpleQuery'? – 2014-10-19 10:32:45

+0

使用基於服務的體系結構我有一種調用服務的非常一致的方式,所以不必每次都寫出'try ... catch',而是每次寫入一次並處理相同的內容。只是更容易,更乏味 – 2014-10-19 10:35:12

回答

2

這將工作。它可以簡化一點:

async() => await this.securityService.LoginAsync(register.UserName, register.Password, true) 

可以寫成

() => this.securityService.LoginAsync(register.UserName, register.Password, true) 

因爲LoginAsync已經返回Task。這就是說,無論何時你處理它們都會有一定的一致性。按照你的方式來完成這項任務並不是真的有害。我認爲這兩種方式都是合理的。

如果LoginAsync不能拋出任何異常(你關心),你根本不需要lambda。當您調用異步方法時,異常通常存儲在Task中。您可以直接將Task傳遞給ExecuteSimpleQuery。如果LoginAsync不符合此模式,則不能執行此操作,因爲異常會觸發得太早。

var loginTask = securityService.LoginAsync(register.UserName, register.Password, true); 
    var objectStore = await ExecuteSimpleQuery(loginTask); 

protected async Task<KeyValuePair<bool, string>> ExecuteSimpleQuery(Task<bool> service) 
{ 
    //... 

    try 
    { 
     success = await service; 
    } 
    catch (Exception exception) 
    { 
     //... 
    } 

    //... 
} 

你可以這樣測試:

var loginTask = Task.Run(() => { throw null; }); 

catch將受到打擊。