2014-09-29 178 views
0

正如我所料,我得到了該場景的編譯器警告。然而,所涉及的方法被稱爲....異步,因爲它們是公共數據IO接口的實現,其具體類有時能夠調用其數據存儲異步(特別是SQL和Mongo)。異步方法返回任務,但實際上不是異步

我通常會放一個「#pragma警告」來防止警告,但有沒有一種技術上更好的解決方法。這裏的問題是,接口暗示(通過命名約定)方法是異步的,我希望消費者等待我的方法調用那些具體類可以確實進行異步調用的情況 - 所以我不想分割接口進入異步和非異步調用。

我可以給Pragma出警告,還是有一些更深層次的警告,我不理解。

這種情況是這樣的;

public interface IGetData 
{ 
    Task<IEnumerable<Person>> GetPeopleAsync(); 
} 

public class GetDataViaSQLServer : IGetData 
{ 
    public async Task<IEnumerable<Person>> GetPeopleAsync() 
    { 
     return await SqlCommand.ExecuteAsync("spoc_getpeople"); // Pseudo code to illustrate the async call 
    } 
} 

public class GetDataViaMongo : IGetData 
{ 
    public async Task<IEnumerable<Person>> GetPeopleAsync() 
    { 
     IEnumerable<Person> people = mongoCollection<Person>(); // Psuedocode illustrating lack of mongo async capability 
     return people; 
    } 
} 

第二類將給編譯器警告,它被聲明爲異步但沒有等待依賴關係。兩個具體類的內部實現對消費者是隱藏的,但命名約定意味着它們應該等待調用返回值;

IGetData dataFetcher = ioc.Resolve<IGetData>(); 
IEnumerable<Person> people = await dataFetcher.GetPeopleAsync(); 

我真的不希望他們看到的任何警告,當他們編譯 - 但(作爲一個例子)蒙戈沒有按執行異步支持,但SQL Server的一個呢。有沒有比使用#pragma停止警告更好的解決方案?

+3

你應該發佈你的代碼,它會讓你更容易明白你的意思。 – 2014-09-29 13:51:19

+1

我對這個問題感到困惑。如果該方法不包含等待,那麼爲什麼它有利於將其標記爲異步?不要忽視警告。刪除async關鍵字。 – 2014-09-29 14:07:24

+0

@EricLippert除非我錯了,否則它會阻止我需要手動構建任務,從而導致更簡潔的代碼。 – PhillipH 2014-09-29 14:09:33

回答

2

我有一個包含這個靜態TaskHelpers類:

public static readonly Task CompletedTask = Task.FromResult<object>(null); 

要創建一個同步實現,然後我只是做:

public Task MyMethodAsync() 
    { 
     //... Do stuff ... 
     return TaskHelpers.CompletedTask; 
    } 

我用的輔助類只是緩存完成的任務。值得慶幸的是,爲已完成的任務使用了一條快速路徑,所以對性能的影響並不差。