Skip to content

Commit 75d716c

Browse files
Refactoring: Inline AsyncHelper into ExpressionExecutor (#405)
1 parent 9ea5a4f commit 75d716c

File tree

5 files changed

+52
-68
lines changed

5 files changed

+52
-68
lines changed

net/DevExtreme.AspNet.Data/Async/AsyncHelper.cs

Lines changed: 0 additions & 38 deletions
This file was deleted.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Linq.Expressions;
5+
using System.Threading;
6+
using System.Threading.Tasks;
7+
8+
namespace DevExtreme.AspNet.Data.Async {
9+
10+
class AsyncOverSyncAdapter : IAsyncAdapter {
11+
public static readonly IAsyncAdapter Instance = new AsyncOverSyncAdapter();
12+
13+
private AsyncOverSyncAdapter() {
14+
}
15+
16+
// NOTE on Task.FromResult vs. Task.Run https://stackoverflow.com/a/34005461
17+
18+
Task<int> IAsyncAdapter.CountAsync(IQueryProvider queryProvider, Expression expr, CancellationToken _)
19+
=> Task.FromResult(queryProvider.Execute<int>(expr));
20+
21+
Task<IEnumerable<T>> IAsyncAdapter.ToEnumerableAsync<T>(IQueryProvider queryProvider, Expression expr, CancellationToken _)
22+
=> Task.FromResult(queryProvider.CreateQuery<T>(expr).AsEnumerable());
23+
}
24+
25+
}

net/DevExtreme.AspNet.Data/Async/ReflectionAsyncAdapter.cs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -136,15 +136,11 @@ static Task<int> InvokeCountAsync(MethodInfo method, IQueryProvider provider, Ex
136136
return (Task<int>)InvokeQueryExtensionMethod(method, query.ElementType, query, cancellationToken);
137137
}
138138

139-
static Task<IEnumerable<T>> InvokeToArrayAsync<T>(MethodInfo method, IQueryProvider provider, Expression expr, CancellationToken cancellationToken) {
140-
var arrayTask = (Task<T[]>)InvokeQueryExtensionMethod(method, typeof(T), provider.CreateQuery(expr), cancellationToken);
141-
return arrayTask.ContinueWith(t => (IEnumerable<T>)t.Result);
142-
}
139+
async static Task<IEnumerable<T>> InvokeToArrayAsync<T>(MethodInfo method, IQueryProvider provider, Expression expr, CancellationToken cancellationToken)
140+
=> await (Task<T[]>)InvokeQueryExtensionMethod(method, typeof(T), provider.CreateQuery(expr), cancellationToken);
143141

144-
static Task<IEnumerable<T>> InvokeToListAsync<T>(MethodInfo method, IQueryProvider provider, Expression expr, CancellationToken cancellationToken) {
145-
var listTask = (Task<List<T>>)InvokeQueryExtensionMethod(method, typeof(T), provider.CreateQuery(expr), cancellationToken);
146-
return listTask.ContinueWith(t => (IEnumerable<T>)t.Result);
147-
}
142+
async static Task<IEnumerable<T>> InvokeToListAsync<T>(MethodInfo method, IQueryProvider provider, Expression expr, CancellationToken cancellationToken)
143+
=> await (Task<List<T>>)InvokeQueryExtensionMethod(method, typeof(T), provider.CreateQuery(expr), cancellationToken);
148144

149145
static object InvokeQueryExtensionMethod(MethodInfo method, Type elementType, IQueryable query, CancellationToken cancellationToken) {
150146
return method

net/DevExtreme.AspNet.Data/DataSourceLoaderImpl.cs

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,25 +17,20 @@ namespace DevExtreme.AspNet.Data {
1717

1818
class DataSourceLoaderImpl<S> {
1919
readonly IQueryable<S> Source;
20-
21-
readonly CancellationToken CancellationToken;
22-
readonly bool Sync;
23-
24-
readonly QueryProviderInfo ProviderInfo;
2520
readonly DataSourceLoadContext Context;
21+
readonly Func<Expression, ExpressionExecutor> CreateExecutor;
2622

2723
#if DEBUG
2824
readonly Action<Expression> ExpressionWatcher;
2925
readonly bool UseEnumerableOnce;
3026
#endif
3127

3228
public DataSourceLoaderImpl(IQueryable<S> source, DataSourceLoadOptionsBase options, CancellationToken cancellationToken, bool sync) {
33-
Source = source;
34-
CancellationToken = cancellationToken;
35-
Sync = sync;
29+
var providerInfo = new QueryProviderInfo(source.Provider);
3630

37-
ProviderInfo = new QueryProviderInfo(source.Provider);
38-
Context = new DataSourceLoadContext(options, ProviderInfo, typeof(S));
31+
Source = source;
32+
Context = new DataSourceLoadContext(options, providerInfo, typeof(S));
33+
CreateExecutor = expr => new ExpressionExecutor(Source.Provider, expr, providerInfo, cancellationToken, sync);
3934

4035
#if DEBUG
4136
ExpressionWatcher = options.ExpressionWatcher;
@@ -170,7 +165,7 @@ Task<int> ExecCountAsync(Expression expr) {
170165
ExpressionWatcher?.Invoke(expr);
171166
#endif
172167

173-
var executor = new ExpressionExecutor(Source.Provider, expr, CancellationToken, Sync);
168+
var executor = CreateExecutor(expr);
174169

175170
if(Context.RequireQueryableChainBreak)
176171
executor.BreakQueryableChain();
@@ -197,7 +192,7 @@ async Task<IEnumerable<R>> ExecExprAsync<R>(Expression expr) {
197192
ExpressionWatcher?.Invoke(expr);
198193
#endif
199194

200-
var executor = new ExpressionExecutor(Source.Provider, expr, CancellationToken, Sync);
195+
var executor = CreateExecutor(expr);
201196

202197
if(Context.RequireQueryableChainBreak)
203198
executor.BreakQueryableChain();

net/DevExtreme.AspNet.Data/ExpressionExecutor.cs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,17 @@ class ExpressionExecutor {
1212
IQueryProvider Provider;
1313
Expression Expr;
1414

15+
readonly QueryProviderInfo ProviderInfo;
1516
readonly CancellationToken CancellationToken;
1617
readonly bool Sync;
1718

18-
public ExpressionExecutor(IQueryProvider provider, Expression expr, CancellationToken cancellationToken, bool sync) {
19+
public ExpressionExecutor(IQueryProvider provider, Expression expr, QueryProviderInfo providerInfo, CancellationToken cancellationToken, bool sync) {
1920
Provider = provider;
2021
Expr = expr;
21-
Sync = sync;
22+
23+
ProviderInfo = providerInfo;
2224
CancellationToken = cancellationToken;
25+
Sync = sync;
2326
}
2427

2528
public void BreakQueryableChain() {
@@ -48,20 +51,23 @@ public void BreakQueryableChain() {
4851
}
4952

5053
public Task<IEnumerable<T>> ToEnumerableAsync<T>() {
51-
if(!Sync)
52-
return CreateAsyncHelper().ToEnumerableAsync<T>(Expr);
53-
54-
return Task.FromResult((IEnumerable<T>)Provider.CreateQuery<T>(Expr));
54+
CancellationToken.ThrowIfCancellationRequested();
55+
return CreateAsyncAdapter().ToEnumerableAsync<T>(Provider, Expr, CancellationToken);
5556
}
5657

5758
public Task<int> CountAsync() {
58-
if(!Sync)
59-
return CreateAsyncHelper().CountAsync(Expr);
59+
CancellationToken.ThrowIfCancellationRequested();
60+
return CreateAsyncAdapter().CountAsync(Provider, Expr, CancellationToken);
61+
}
62+
63+
IAsyncAdapter CreateAsyncAdapter() {
64+
if(Sync)
65+
return AsyncOverSyncAdapter.Instance;
6066

61-
return Task.FromResult(Provider.Execute<int>(Expr));
67+
return CustomAsyncAdapters.GetAdapter(Provider.GetType())
68+
?? new ReflectionAsyncAdapter(ProviderInfo);
6269
}
6370

64-
AsyncHelper CreateAsyncHelper() => new AsyncHelper(Provider, new QueryProviderInfo(Provider), CancellationToken);
6571
}
6672

6773
}

0 commit comments

Comments
 (0)