4

我有一个这样定义的权限列表:

private List<PermissionItem> permissionItems;
private ReadOnlyCollection<PermissionItem> permissionItemsReadOnly;

该列表是通过后台线程从 Web 服务中检索的。只读版本由 List 版本填充。

我将此列表公开给我的(相当大的)应用程序的其余部分,如下所示:

public IQueryable<PermissionItem> PermissionItems
{
   get
   {
       // Make sure that the permissions have returned.  
       // If they have not then we need to wait for that to happen.
       if (!doneLoadingPermissions.WaitOne(10000))
           throw new ApplicationException("Could not load permissions");

       return permissionItemsReadOnly.AsQueryable();
   }
}

这一切都很好。用户可以请求权限并在加载后获取它们。

但是,如果我在构造函数中有这样的代码(在不同的类中):

ThisClassInstanceOfThePermisssions = SecurityStuff.PermissionItems;

然后我相当确定这将阻止直到权限返回。但在实际使用权限之前,它不需要阻塞。

我读过 IQueryable 是“延迟加载”。(我在我的实体框架代码中使用了这个功能。)

有没有办法可以更改它以允许随时引用我的 IQueryable,并且仅在实际使用数据时才阻止?

注意:这是一个“值得拥有”的功能。实际上加载权限不会花费太长时间。所以如果这是一个“自己动手”查询/表达式的东西,那么我可能会通过。但我很好奇如何让它发挥作用。

4

2 回答 2

5

是的,这是可能的。首先,您可能应该切换到 IEnumerable,因为您没有使用任何 IQueryable 功能。接下来,您需要实现一个新的迭代器:

public IEnumerable<PermissionItem> PermissionItems
{
   get
   {
        return GetPermissionItems();
   }
}
static IEnumerable<PermissionItem> GetPermissionItems()
{
       // Make sure that the permissions have returned.  
       // If they have not then we need to wait for that to happen.
       if (!doneLoadingPermissions.WaitOne(10000))
           throw new ApplicationException("Could not load permissions");

       foreach (var item in permissionItemsReadOnly) yield return item;
}

The event will only be waited on if the caller of the property enumerates the IEnumerable. Just returning it does nothing.

于 2012-08-08T21:16:41.193 回答
1

看看Lazy<T>课堂。

延迟初始化在第一次访问Lazy.Value属性时发生。使用 Lazy 实例来延迟创建大型或资源密集型对象或执行资源密集型任务

于 2012-08-08T21:10:08.343 回答