如何使用 async 和 await 使方法异步?

Posted

技术标签:

【中文标题】如何使用 async 和 await 使方法异步?【英文标题】:How to make a method async with async and await? 【发布时间】:2019-01-17 13:21:09 【问题描述】:

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

【问题讨论】:

为什么?大部分工作都是cpu绑定的,你不会得到任何东西。 我在 wpf 应用程序中使用它,所有其他方法都是异步的。所以也需要这样做。 @summ - 不,你没有。 你的意思是,你想在后台线程上运行它? 是的可能是..我从其他地方调用这个方法 【参考方案1】:

async-await 的原因是,每当您的线程必须等待某个其他进程完成时,您的线程可以环顾四周,看看它是否可以做一些有用的事情,而不是无所事事地等待。

这对于面向通信的任务特别有用:从数据库查询数据、从 Internet 获取信息、将数据写入磁盘等。通常在这些情况下,您的线程不会做任何事情,而是等待其他进程完成完成。

如果您的线程命令另一个线程进行一些冗长的计算,通常使用 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 似乎只是在创建一个表达式。在制作异步版本之前,您应该确保让另一个线程执行此操作并不比让您的线程执行此操作更昂贵

【讨论】:

以上是关于如何使用 async 和 await 使方法异步?的主要内容,如果未能解决你的问题,请参考以下文章

async和await

async和await

async和await

async和await

异步编程之Async,Await和ConfigureAwait的关系

Async和Await 异步方法