WCF 资源上的异步调用

Posted

技术标签:

【中文标题】WCF 资源上的异步调用【英文标题】:Async call on WCF resource 【发布时间】:2017-09-11 13:06:12 【问题描述】:

我正在构建 WCF 服务,我需要对构建异步方法进行一些说明。

功能应该是当一个请求到达时,它包含一个授权令牌形式的认证信息,它会被检查,如果授权通过,那么实际的功能就会被执行。

首先,Service1.cs 包含这个方法:

 public async Task<string> CreateClass(string name, int departmentId)
    
        Class result = null;
        bool authResult = await System.Threading.Tasks.Task.Run(() =>
        
            return authCtr.AuthenticateToken();
        );
        if (authResult)
        
            result = await System.Threading.Tasks.Task.Run(() =>
            
                return classCtr.CreateClass(name, departmentId);
            );
        
        return result != null ?
            JsonConvert.SerializeObject(result, Formatting.Indented) :
            string.Format(response.StatusCode + "," + response.StatusDescription);
    

在这个例子中,AuthenticateToken() 和 CreateClass() 方法都是同步的,它们分别负责对各自表的创建和读取数据库操作。 在阅读了更多之后,我想到了将这两种方法修改为异步并修改以前的代码,但是在阅读了越来越多之后,混乱袭来,我无法决定哪种方式更好/正确。如果我要选择,那么我会将所有方法重写为异步并在服务中将它们调用为:

public async Task<string> CreateClass(string name, int departmentId)
    
        Class result = null;
        if(await authCtr.AuthenticateToken())
        
            result = await classCtr.CreateClass(name, departmentId);
        
        return result != null ?
            JsonConvert.SerializeObject(result, Formatting.Indented) :
            string.Format(response.StatusCode + "," + response.StatusDescription);
    

所以问题1:这些方式中的任何一种实际上是异步的,还是完全一团糟?

问题2:如果我要异步更改控制器方法,是否可以修改它们,使它们看起来像这样:

return await System.Threading.Tasks.Task.Run(() =>

        //DO DB STUFF

【问题讨论】:

【参考方案1】:

如果您想异步编写代码,那么您需要真正深入到实际 .net 框架本身的最后一层,例如SqlCommand.ExecuteReaderAsync 用于 ADO.Net(在所有主要的 ORM 中都有相应的包装器)。

这将为您带来非阻塞调用的好处,这意味着服务于 WCF 操作的线程将被释放,直到 IO 返回数据。如果您将调用包装在Task.Run() 中,您实际上是在您的应用程序域中使用通用线程池,因此您无法像使用完整的await 一样从优化线程的框架中受益。

本质上:是的,如果您想完全异步使用 WCF,请使用带有await 的 DB 访问。 否则,在没有Task.Run() 的情况下同步执行所有操作,以避免线程等待并简单地返回Task.FromResult()

【讨论】:

惊人的信息,谢谢!因此,如果我在控制器中使用 await db.SaveChangesAsync(),那将是“实际 .net 框架的最后一级”。我说的对吗?

以上是关于WCF 资源上的异步调用的主要内容,如果未能解决你的问题,请参考以下文章

如何异步调用我的 WCF 服务?

WCF服务需要调用异步

WCF 异步方法调用返回响应对象

WCF 异步调用 - 事件处理程序中的异常

ASP.NET Web 表单 - 如何异步调用 WCF 异步方法?

同时等待多个具有独立延续的 WCF 异步调用