WCF同步到异步转换

目录

介绍

使契约异步

接口

实现

将同步方法转换为异步

原始同步方法

异步修改

从同步方法调用异步方法

从异步方法调用异步方法

结论


介绍

本文提供了一些关于如何将现有的工作WCF契约增量地转换为异步的想法,以便在一段时间内轻松测试功能,并且契约可以在任何阶段正常运行。

这里提出的想法不是原创的,而是基于网络搜索。没有一位作者可以感谢,但我要感谢所有那些花时间分享知识的开发人员。

我遇到的问题是工作的WCF IIS托管服务。契约都是同步的。它们涉及一些数据库活动,并呼叫另一个第三方服务。我想尽可能多地从契约中取出。

从一般阅读来看,似乎异步编程会产生收益(主要是在IIS服务器中不浪费线程)。我想清楚我是一个异步的学习者,这是我的发现之旅的编年史。希望那里的专家不会发现太多不同意的意见。

有许多事情必须解决。

  • 在不破坏界面的情况下将契约更改为异步的。
  • 将同步方法转换为异步。
  • 从同步方法调用异步方法。

注意:需要 .NET Framework 4.6.1或更高版本才能使用asyncawait关键字。

让我们按顺序解决这些问题。

使契约异步

将接口契约声明的返回类型T(如果有)更改为Task<T>。对实现代码执行相同操作,并将async关键字添加到实现代码声明中。

接口

[OperationContract]
        [WebInvoke(
            Method = "POST",
            BodyStyle = WebMessageBodyStyle.Bare,
            ResponseFormat = WebMessageFormat.Json,
            RequestFormat = WebMessageFormat.Json)]
        Task<TransList> ProcessRequests(TransList incoming);

实现

public async Task<TransList> ProcessRequestsV2(TransList incoming)
        {
TransList response = new TransList;
DoSomeStuff;
return response;
}

一旦声明就绪,代码仍应编译并生成编译器警告CS4014

警告CS4014CS1998:当您完成转换时,这些警告会随之而来。它们提供了指向尚未实现异步的指针。代码仍然有效,您的服务仍然有效。

将同步方法转换为异步

显示的方法来自DataBase辅助类。它显示了使用内置的.framework异步方法从数据库中读取数据。

原始同步方法

public bool GetProcessAllowed(string user)
      {
          const string sSql = "proc_GetProcessAllowed";
          using (var conn = new SqlConnection(_msConn))
          {
              using (var cmd = new SqlCommand(sSql, conn))
              {
                  conn.Open();
                  cmd.CommandType = CommandType.StoredProcedure;
                  cmd.Parameters.AddWithValue("@user", user);
                  using (var r = cmd.ExecuteReader())
                  {
                      if (r.Read())
                      {

                         return r.GetBoolean(0);

                      }
                      throw new ApplicationException("Dt.GetProcessAllowed not able to access database.");

                  }
              }
          }
      }

异步修改

public async Task&lt;bool&gt; GetProcessAllowed(string user)
{
    const string sSql = "proc_GetProcessAllowed";
    using (var conn = new SqlConnection(_msConn))
    {
        await conn.OpenAsync();
        using (var cmd = new SqlCommand(sSql, conn))
        {
            //conn.Open();
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.AddWithValue("@user", user);
            using (var r = await cmd.ExecuteReaderAsync())
            {
                if (r.Read())
                {

                        return r.GetBoolean(0);

                }
                throw new ApplicationException("Dt.GetProcessAllowed not able to access database.");

            }
        }
    }
}

从同步方法调用异步方法

为了清楚起见,调用方法仍然是同步的。它没有将异步添加到其声明中,并且返回类型未更改。以下代码段显示对被调用方法的同步版本(已注释掉)的原始调用以及对异步版本的新调用。

请注意使用Result属性来返回原始布尔变量。

 //bool getProcessAllowed = _db.GetProcessAllowed(credentials.UserId);
 //bool writeProcessRunning = _db.WriteProcessRunning(credentials.UserId, true);
 Task<bool> getProcessAllowedAsync = _db.GetProcessAllowed(credentials.UserId);
 Task<bool> writeProcessRunningAsync = _db.WriteProcessRunning(credentials.UserId, true);
 bool getProcessAllowed = getProcessAllowedAsync.Result;
 bool writeProcessRunning =  writeProcessRunning.Result;
if (getProcessAllowed && writeProcessRunning)
 {Do some stuff}

从异步方法调用异步方法

这里,调用方法已转换为异步。async关键字已添加到其声明中,其返回类型是Task<T>,因此它可以等待(await)从被调用方法返回的内容。

以下代码段显示对同步版本方法(已注释掉)的原始调用以及对异步版本的新调用。

注意使用await而不是Result属性来返回原始的布尔变量。

//bool getProcessAllowed = _db.GetProcessAllowed(credentials.UserId);
 //bool writeProcessRunning = _db.WriteProcessRunning(credentials.UserId, true);
 Task<bool> getProcessAllowedAsync = _db.GetProcessAllowed(credentials.UserId);
 Task<bool> writeProcessRunningAsync = _db.WriteProcessRunning(credentials.UserId, true);
 bool getProcessAllowed = await getProcessAllowedAsync;
 bool writeProcessRunning = await writeProcessRunningAsync;
if (getProcessAllowed && writeProcessRunning)
 {Do some stuff}

结论

对我来说,关键是要理解上面显示的同步和异步方法之间的关系。

花了一段时间才意识到将异步关键字添加到方法并将其返回值从T更改为Task<T>仍然允许它同步运行。

在您实现更改时,编译器警告提供了一个很好的指导,您正在处理的部分仍需要更多工作。

 

原文地址:https://www.codeproject.com/Tips/1274500/WCF-Sync-to-Async-Conversion

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值