2017-04-15 98 views
0

我正在构建一个WCF服务,我需要一些关于构建异步方法的说明。WCF资源异步调用

功能应该是当请求到达时,它包含以authorizationToken的形式的认证信息,该认证信息被检查并且如果授权通过,则执行实际功能。

首先,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()是同步于该示例,并且他们负责在各表创建和读取DB操作。 在阅读了更多内容之后,我想到修改这两种方法是异步并修改了前面的代码,但是在阅读越来越多的内容后,混淆命中,我无法确定哪种方式更好/更正确。如果我选择的话,我会去重写所有的方法是异步,并呼吁他们的服务为:

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 
} 

回答

0

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

这会给你非阻塞调用的好处,这意味着服务于WCF动作的线程将被释放,直到IO返回数据为止。如果您将呼叫打包在Task.Run()中,那么您实际上在您的应用程序域中使用了通用线程池,因此您无法像优化线程一样使用完整的await

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

+0

很棒的信息,谢谢! 因此,如果我要在控制器内部使用await db.SaveChangesAsync(),那将是“实际.net框架的最后一个级别”。我对吗? – Crunchh

+0

@Crunchh没错。 – zaitsman