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 资源上的异步调用的主要内容,如果未能解决你的问题,请参考以下文章