我了解async和await的用法,当我看到使用的任何方法都可以轻松理解时,却无法自己完成。
public static Expression<Func<T, bool>> GetExpression<T>(Field filter)
{
ParameterExpression param = Expression.Parameter(typeof(T), "t");
Expression exp = null;
if (filter != null)
{
exp = GetExpression<T>(param, filter);
}
return Expression.Lambda<Func<T, bool>>(exp, param);
}
private static Expression GetExpression<T>(ParameterExpression param,Field filter)
{
var stringMember = Expression.Call(asString, Expression.Convert(member, typeof(object)));
ConstantExpression constant = Expression.Constant(filter.TextToBeFiltered.ToString().ToLower());
switch (filter.Operation)
{
case FilterEnum.Equals:
return Expression.Equal(stringMember, constant);
case FilterEnum.DoesNotEqual:
return Expression.NotEqual(stringMember, constant);
}
return null;
}
如何使用async和await使这些方法异步?
答案 0 :(得分:0)
异步等待的原因是,每当您的线程必须等待其他进程完成时,您的线程便可以环顾四周,看看它是否可以做一些有用的事情,而不是无所事事地等待。
这对于面向通信的任务特别有用:从数据库查询数据,从Internet提取信息,将数据写入磁盘等。通常,在这些情况下,您的线程什么都不做,只是等到另一个进程完成。
通常,如果您的线程命令另一个线程进行一些冗长的计算,则使用async-await并不有意义。这样做的唯一原因是,冗长的计算需要花费大量时间,并且您希望在计算过程中保持呼叫者的响应能力。但即使如此:对于您的函数的调用者,它的外观应类似于调用具有有意义的async-await的函数,例如从数据库中获取数据的函数等。
在您的示例中,似乎创建表达式不是一个冗长的操作。这通常是一个很短的过程。但是,即使这是一个冗长的操作,在线程什么也不做的情况下,命令另一个线程来执行任务也没有用。
如果线程是UI线程,则可能会使函数异步,但前提是表达式的创建足够长,以使操作员能够注意到无响应的UI。
您可以使用Task.Run
调用您的非异步GetExpression来创建GetExpression的异步版本:
async Task<Expression> GetExpressionAsync<T>(ParameterExpression param, Field filter)
{
return await Task.Run( () => GetExpression(param, filter);
}
现在,您可以异步其他GetExpression函数的版本:
async Task<Expression<Func<T, bool>>> GetExpressionAsync<T>(Field filter)
{
ParameterExpression param = Expression.Parameter(typeof(T), "t");
Expression exp = null;
if (filter != null)
{
exp = await GetExpressionAsync<T>(param, filter);
}
return Expression.Lambda<Func<T, bool>>(exp, param);
}
但是再次:GetExpression
似乎只是在创建一个表达式。在创建此版本的异步版本之前,应确保让另一个线程执行此操作比让您的线程执行此操作更昂贵