2014-09-29 139 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; 
    } 

我用的辅助类只是缓存完成的任务。值得庆幸的是,为已完成的任务使用了一条快速路径,所以对性能的影响并不差。