【问题标题】:WCF Synchronous vs AsynchronousWCF 同步与异步
【发布时间】:2013-04-16 15:48:39
【问题描述】:

一直在看MSDN和codeproject,但还是有点迷茫。

同步服务与异步服务。

我有一个 WCF 服务端点。该服务将 2way SSL 应用于其 web.config 文件。 客户端是一个基于 Oracle 的 java Weblogic Suite。这有自己的私钥和公钥。客户端需要与我们的服务进行异步和同步通信。

我只能在服务器端更改内容

http://www.codeproject.com/Articles/91528/How-to-Call-WCF-Services-Synchronously-and-Asynchr

http://msdn.microsoft.com/en-us/library/ms731177.aspx

以下代码是SVC、cs文件的同步部分:-

public getQuoteSyncResponse1 getQuoteSync(getQuoteSyncRequest request)
     {
        // Create new response
        getQuoteSyncResponse1 res = new getQuoteSyncResponse1();

        res.GetQuoteSyncResponse = new GetQuoteSyncResponse();
        res.GetQuoteSyncResponse.Header = new GetQuoteResponseHeaderType();
        res.GetQuoteSyncResponse.Response = new GetQuoteSyncResponseType();

        // Create and populate header
        res.GetQuoteSyncResponse.Header.MessageId = request.GetQuoteRequestSync.Header.MessageId;
        res.GetQuoteSyncResponse.Header.Timestamp = request.GetQuoteRequestSync.Header.Timestamp;
        res.GetQuoteSyncResponse.Header.QuoteId = request.GetQuoteRequestSync.Header.QuoteId;
        res.GetQuoteSyncResponse.Header.CarrierId = request.GetQuoteRequestSync.Header.CarrierId;


        List<RejectionType> rj = new List<RejectionType>();


        string _sTotalEmployees = request.GetQuoteRequestSync.Request.Employer.TotalEmployees;
        int _TotalEmployees = 0;
        if (int.TryParse(_sTotalEmployees, out _TotalEmployees) == false)
        {


            RejectionType rt;
            rt = new RejectionType();
            rt.ReasonCode = "R01";
            rt.ReasonDescription = "Invalid Number of Employees";

            rj.Add(rt);

            res.GetQuoteSyncResponse.Response.Rejections = rj.ToArray();

            res.GetQuoteSyncResponse.Response.ReceiptStatus = AcceptanceContentType.Reject;

            return res;
        }

        res.GetQuoteSyncResponse.Response.ReceiptStatus = AcceptanceContentType.Success;

        List<QuoteType> q = new List<QuoteType>();

        QuoteType qt;

        qt = new QuoteType();
        qt.PlanId = "P345678";
        qt.EEPremium = 1220;
        qt.EESPPremium = 2222;
        qt.EEDepPremium = 3333;
        qt.EEFamilyPremium = 4444;
        qt.TotalMonthlyPremium = 3456;
        qt.CoverageEffectiveDate = DateTime.Now;

        q.Add(qt);

        res.GetQuoteSyncResponse.Response.Quotes = q.ToArray();

        return res;}

所以服务的这个同步部分正在工作。现在,我如何使用它来将其转换为异步等效项?

我应该在 cs 文件中启动异步方法吗?还是在 svc 文件中?我很困惑……

 public getQuoteAsyncResponse getQuoteAsync(getQuoteAsyncRequest request, AsyncCallback callback, Object state)
    {
        // Create new response
        getQuoteAsyncResponse res = new getQuoteAsyncResponse();

        return new getQuoteAsyncResponse();
    }

我对回调 deli-gator、对象状态等有所了解,但有人可以为我进一步说明这一点吗?如何格式化服务的异步部分?网络上有很多例子……但都非常混乱。我一定对这个概念有一些内在的误解。

编辑:- 我在答案中被告知,服务器端不需要任何操作来进行异步通信。但是我发现了这个:-

在 WCF 中实现异步操作 正如 WCF 管道使客户端能够异步调用服务器操作,而服务器不需要知道任何有关它的信息,WCF 也允许异步定义服务操作。所以像这样的操作:

[OperationContract]
string DoWork(int value);

…可能在服务合同中表示为:

[OperationContract(AsyncPattern = true)]
IAsyncResult BeginDoWork(int value, AsyncCallback callback, object state);

string EndDoWork(IAsyncResult result);

请注意,这两种形式是等效的,并且在 WCF 元数据中无法区分:它们都公开了一个名为 DoWork[1] 的操作:

【问题讨论】:

    标签: asp.net wcf ssl asynchronous


    【解决方案1】:

    异步部分需要在客户端完成。这意味着您可能正在做类似的事情: var response = ServiceReference.GetSomething();

    相反,创建一个代理来获取回调。每当回调收到响应时,创建和触发(或调用)事件(或委托)。在上面的语句中,您显然是在等待将响应分配到变量中,然后再移动到下一行。

    相反,你可以

    1. 在Service合约上,一定要用[OperationContract(IsOneWay = true)]装饰
    2. 如果您使用 ServiceReference 或 serviceutil,它将自动创建“传入事件”并为您完成所有客户端异步工作。
    3. 如果您使用 TCP,请同时创建一个回调合约,然后在客户端上您可以执行类似的操作 ServiceReference1.IncomingSomething += 新事件处理程序。 现在您可以执行 ServiceReferecnce1.GetSomething(),响应将转到事件处理函数。
    4. 如果这是 RESTFUL:

        public void MakeAsyncRequest(string url, string contentType)
                  {
                      try
                      {
                          HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                          request.ContentType = contentType;
                          request.Method = WebRequestMethods.Http.Get;
                          request.Timeout = 10000;
                          request.Proxy = null;
      
                          request.BeginGetResponse(new AsyncCallback(ReadCallback), request);
                      }
                      catch (Exception ex)
                      {
                          LogManager.LogException(ex);
                      }
                  }
      
                  private void ReadCallback(IAsyncResult asyncResult)
                  {
                      HttpWebRequest request = (HttpWebRequest)asyncResult.AsyncState;
                      string strContent = string.Empty;
                      string s;
      
                      try
                      {
                          using (HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asyncResult))
                          {
                              Stream responseStream = response.GetResponseStream();
                              using (StreamReader sr = new StreamReader(responseStream))
                              {
                                  //Need to return this response 
                                  strContent = sr.ReadToEnd();
                              }
                          }
                      }
                      catch (Exception ex)
                      {
                          throw;
                      }
                  }
      

    【讨论】:

    • 只是为了添加更多的 cmets:- >> 是的,这是一个 RESTful 服务。 >> 是的,这是面向 TCP 的通信。 >> 我无法在客户端添加任何内容,客户端未由我处理。我唯一能与客户端协调的是 2way SSL 通信、RESTful Soap XML 包和包的数据结构。那么你添加的代码是在客户端还是服务器端呢?
    • 您对代码的理解是正确的,这意味着它是在客户端完成的。您不能在服务中有异步/同步逻辑。它必须在客户端完成。
    • 例如,如果客户端执行var response = ServiceReference.GetSomething();,那么你在服务端做什么都没有关系,因为客户端会等待响应在移动到下一行之前。 客户端设计模式使用服务同步或异步。
    • hmmm....好吧,客户端是由其他人构建的。在编码的那部分,我没有任何参与。我从服务器端发布了我的代码。是否需要在服务器端实现任何东西以使其与客户端异步兼容?
    • 不。在这种情况下,您无能为力。服务端没有关心同步/异步的设计模式。这一切都在客户端。由于您没有在客户端中扮演任何角色,因此您无能为力。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-23
    • 2012-11-03
    • 1970-01-01
    相关资源
    最近更新 更多