简体   繁体   English

如何从MVC4 WebAPI异步调用WCF方法

[英]How to call a WCF method asynchronously from MVC4 WebAPI

I am new to the WebApi, .Net world and am totally confused with all the information available as to what approach I should take. 我是WebApi,.Net领域的新手,对所有可用信息都感到困惑,我应该采取哪种方法。 I have created a WebService using MVC4 WebApi that Twilio calls when a text message is received. 我已经使用MVC4 WebApi创建了一个WebService,当收到文本消息时Twilio会调用它。 I need to respond to this text message. 我需要回复此短信。 I am consuming a WCF method which is currently being called synchronously. 我正在使用WCF方法,该方法当前正在同步调用。 Since it is possible that my process can take longer than 3-5 seconds to process a reply to the text message the connection to Twilio gets disconnected due to timeout. 由于我的过程可能需要超过3-5秒的时间来处理对文本消息的答复,因此与Twilio的连接由于超时而断开了连接。 So I am looking for ways to call this WCF method asynchronously. 因此,我正在寻找异步调用此WCF方法的方法。 My question is to call the WCF method (I am calling the WCF using a Object Factory and using) do I need to update the contract to say Async? 我的问题是调用WCF方法(我正在使用对象工厂来调用WCF并使用)我是否需要更新合同以说“异步”? I am little confused on that. 我对此一点困惑。

BTW my Web Service is in IIS7 and am using .Net4.5 framework and MVC4 WebApi . 顺便说一句,我的Web服务在IIS7中,并且正在使用.Net4.5框架和MVC4 WebApi。

My code is somewhat like this: So I would like to call the SendSms part asynchronously. 我的代码有点像这样:所以我想异步调用SendSms部分。 How do I do that? 我怎么做? Can I simply use Task.Run Async and Await? 我可以简单地使用Task.Run Async和Await吗?

 using Twilio.Mvc;
 using Twilio.TwiML.Mvc;
 using Twilio.TwiML;


public class SmsController : ApiController
{
    [HttpPost]
    public HttpResponseMessage Post([FromBody]SmsRequest smsReq)
    {
            var response = new Twilio.TwiML.TwilioResponse();
            //validation checks..

            try
            {

                -- call to WCF to get the List of sms to be sent 
                if ((txtMessageResponse != null) && (txtMessageResponse.SmsMessageInfo.Count > 0))
                {
                    _smsStagingList = txtMessageResponse.SmsMessageInfo;
                    foreach (TextMessageStaging prepareTextMessageResponse in _smsStagingList)
                    {
                        smsDTO textMessageItems = new smsDTO();
                        textMessageItems.PhoneNumber = prepareTextMessageResponse.PhoneNumber;
                        textMessageItems.SmsMessage = prepareTextMessageResponse.SmsMessageBody;

                        isTxtMessageSent = SendSms(textMessageItems);

                        //If the messages were sent then no need to set the flag to be updated 
                        if (isTxtMessageSent)
                        {
                            txtMessageStatusToBeUpdated = false;
                        }
                    }
                    return Request.CreateResponse(HttpStatusCode.OK, twilioResponse.Element);
                }
                else
                {
                    //send error response
                }
            catch (Exception msgProcessingError)
            {
              //send error response again as processing error
            }
            finally
            {
             //set the outbound flag in the table
            }
     }


    private bool SendSms(smsDTO textMessageItems)
    {
        bool isTxtMessageSent = false;
        PushMessageRequest txtMessageRequest = new PushMessageRequest();
        PushMessageResponse txtMessageResponse = null;
        txtMessageRequest.SmsMessageInfo = new SendTextMessage(); //instantiate the dto

        txtMessageRequest.SmsMessageInfo.ToPhone = textMessageItems.PhoneNumber;
        txtMessageRequest.SmsMessageInfo.TextMessage = textMessageItems.SmsMessage;
        try
        {
            using (ITextService textService = ObjectFactory.SendSmsMessage())
            {
                txtMessageResponse = textService.SendSmsMessage(txtMessageRequest);
            }

            isTxtMessageSent = txtMessageResponse.IsSuccessful;
        }
        catch (Exception ex)
        {
            isTxtMessageSent = false;
        }      
        return isTxtMessageSent;
    }          

Twilio evangelist here. Twilio的传播者在这里。

OK, so you have a Web API method in which you call a WCF method that is potentially long running. 好的,因此您有一个Web API方法,在其中调用可能长期运行的WCF方法。 There are two problems to solve here: 这里有两个问题要解决:

  1. How do you call the WCF method in a way that does not block the Web API method from returning a response 如何以不阻止Web API方法返回响应的方式调用WCF方法
  2. How do you get Twilio to wait until the WCF method has finished 您如何让Twilio等待WCF方法完成

I wrote a blog post a while ago that shows you how to create an indefinite wait loop in an IVR by leveraging .NET's Task Parallel library and the loop attribute on Twilios <Play> verb. 不久前,我写了一篇博客文章 ,向您展示如何利用.NET的Task Parallel库和Twilios <Play>动词上的loop属性在IVR中创建不确定的等待循环。

The gist of the post is that you can use the TPL's StartNew method to start the long running WCF method on a new thread. 该帖子的要旨是,您可以使用TPL的StartNew方法在新线程上启动长期运行的WCF方法。 This lets ASP.NET continue and lets you return some TwiML so Twilio does not end the call. 这使ASP.NET可以继续,并允许您返回一些TwiML,因此Twilio不会结束呼叫。 Then you pair that with a continuation which lets you know when the WCF service request is done and you can signal back to Twilio using the REST API to redirect the in-progress call to a new set of TwiML instructions. 然后,将其与一个延续配对,让您知道WCF服务请求何时完成,并且可以使用REST API信号回Twilio,以将正在进行的调用重定向到一组新的TwiML指令。

Hope that helps. 希望能有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM