最近,我们已经移动到EF 6,我们已经开始使用EF异步命令。 例如,在我的存储库中,我有以下方法:
// Gets entities asynchron in a range starting from skip.
// Take defines the maximum number of entities to be returned.
public async Task<IEnumerable<TEntity>> GetRangeAsync(int skip, int take)
{
var entities = this.AddIncludes(this.DbContext.Set<TEntity>())
.OrderBy(this.SortSpec.PropertyName)
.Skip(skip)
.Take(take)
.ToListAsync();
return await entities;
}
现在我必须修改异步数据检索的UI。 下面是我的UI类;该类绑定到WPF。
public sealed class RepositoryCollectionView<TEntity, TEntityViewModel> : IList<TEntityViewModel>,
ICollectionView,
IEditableCollectionView,
IComparer
...
public TEntityViewModel this[int index]
{
get
{
return await this.GetItem(index).Result;
}
set
{
throw new NotSupportedException();
}
}
...
...
...
问题:在UI中我创建了一个名为GetItemAsync(index)的新方法,我需要从Indexer调用此方法;
当我将关键字async写入索引器时:
public async TEntityViewModel this[int index]
我收到以下错误“modfier'async'对此商品无效”
有什么想法吗?任何帮助将不胜感激!
答案 0 :(得分:6)
你根本无法使索引器异步。从C#5规范的第10.15节开始:
使用
async
修饰符的方法或匿名函数称为异步函数。
async
被列为 methods 的有效修饰符之一(第10.6节),但不适用于索引器(10.9)。
请记住,异步方法只能返回void
,Task
和Task<T>
- 但您不需要 setter < / em>接受Task<T>
或Task
,那么该属性类型有用的是什么? (如果你不支持它,为什么即使还有一个setter?)
鉴于听起来好像调用者已经可以使用GetItem
- 如果它返回GetItemAsync
,则应为Task<TEntityViewModel>
- 我不认为索引器会帮助您
答案 1 :(得分:1)
这不是可能的属性不能是异步的。 Source
你可以做的是调用asyncrounous方法并等待它完成,但它会阻止(没有async
表示没有await
)。
答案 2 :(得分:1)
从技术上讲,您无法使索引器异步。但是,您可以让get indexer从异步方法返回Task
或返回Task
。达到相同的目的。
public class AsyncIndexer
{
public Task<int> this[int i] => GetValue(i);
public Task<string> this[string s] => Task.Run(async () =>
{
await Task.Delay(3000);
return s;
});
private async Task<int> GetValue(int i)
{
await Task.Delay(3000);
return i;
}
}
class Program
{
static void Main(string[] args)
{
Task.Run(async () =>
{
var asyncIndexer = new AsyncIndexer();
Console.WriteLine(await asyncIndexer[2]);
}).Wait();
}
}
不幸的是,setter不能返回任何内容,因此async setter绝不可能,因为await语句需要返回一个任务。
您能想象一下语法吗?
await (asyncIndexer[2] = 2)
我很乐意:p