如何使方法与async异步并等待?

时间:2018-08-10 01:48:01

标签: c# .net async-await

我了解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使这些方法异步?

1 个答案:

答案 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似乎只是在创建一个表达式。在创建此版本的异步版本之前,应确保让另一个线程执行此操作比让您的线程执行此操作更昂贵