【问题标题】:C#: Make System.Data.Services.Client.DataServiceQuery async by defaultC#:默认情况下使 System.Data.Services.Client.DataServiceQuery 异步
【发布时间】:2018-07-24 20:51:44
【问题描述】:

Mono.Android 要求我进行异步查询。我可以这样做:

DataServiceQuery<T> dataServiceQuery = query as DataServiceQuery<T>;
return (new TaskFactory<IEnumerable<T>>()).FromAsync(dataServiceQuery.BeginExecute(null, null), asyncResult => dataServiceQuery.EndExecute(asyncResult)).Result;

问题是我不想在每次查询时都调用这个方法,因为这会强制使用我的库的用户调用该方法,否则 Mono 会崩溃,所以我想做 DataServiceQuery默认情况下执行此操作。我可以通过覆盖 DataServiceQuery 中的 GetEnumerator() 函数来做到这一点,但它的构造函数是私有的,所以我不允许这样做。我想我剩下的唯一选择是用我的更改重新编译 System.Data.Services.Client.dll。也许 DataServiceContext 有一个技巧,但老实说我没有选择。

感谢您的帮助, 马克西姆

【问题讨论】:

  • 为什么不在你的方法中使用回调?当您库的用户查询您的方法时,他们调用yourLib.ExecuteQuery(query, (result) =&gt; { ... });,您的方法采用ExecuteQuery(string Query, Action&lt;List&lt;T&gt;&gt; Callback)。但不能肯定地说,需要更多信息
  • 查询是 DataserviceQuery 上的 LINQ 查询
  • 类似于“从 lib.Items 中的项目选择项目”,而不是“lib.GetAsync(从 lib.Items 中的项目选择项目)”
  • 是的,没关系。但我的意思是,根据需要创建查询。在你有TaskFactory的查询中,创建一个新任务,运行你的查询并在你有一个Task.Factory.StartNew(async () =&gt; { ... callback?.invoke(asyncResult)...});时返回结果
  • 我给出的代码示例应该在用户查询时自动运行

标签: c# android xamarin mono odata


【解决方案1】:

无法自动执行此操作,但您可以通过创建一个名为 SelectAsync 的新 Select 函数来使您的语句更好。

事实上,这也解决了 OData 和 LINQ 的一个问题,因为您必须将 Selects 包装在匿名类型中,现在您可以在查询之后调用 Select(这需要更长的时间,因为您要查询整个类,但这对我来说不是问题)。

这是 SelectAsync 扩展方法的代码:

public static IEnumerable<T> SelectAsync<T>(this IQueryable<T> queryable)
{
    return queryable.SelectAsync(x => x);
}

public static IEnumerable<TResult> SelectAsync<T, TResult>(this IQueryable<T> queryable, Function<T, TResult> selector)
{
    var dataServiceQuery = queryable as DataServiceQuery<T>;
    return Task.Run(async () => (await (new TaskFactory<IEnumerable<T>>()).FromAsync(dataServiceQuery.BeginExecute, dataServiceQuery. EndExecute, null)).Select(selector)).Result;
}

在 Mono.Android 中使用 LINQ 执行查询现在更加直观。

var itemNames = Items.Where(item => item.ID == 0).Select(item => item.Name);
var goodCars = Cars.Where(car => car.Fuel >= 0.5);

翻译为:

var itemNames = Items.Where(item => item.ID == 0).SelectAsync(item => item.Name);
var goodCars = Cars.Where(car => car.Fuel >= 0.5).SelectAsync();

据我所知,这是因为 System.Data.Services 目前在 Mono.Android 中不完全支持。这是一个很好且直观的解决方法。

来源:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-29
    • 2014-08-21
    • 2010-12-02
    • 2012-11-24
    • 2010-12-05
    • 2013-09-01
    • 1970-01-01
    相关资源
    最近更新 更多