WCF同步与异步

时间:2013-04-16 15:48:40

标签: asp.net wcf ssl asynchronous

我一直在关注MSDN和codeproject,但我仍然有点困惑。

同步服务与异步服务。

我有一个WCF服务端点。此服务在其web.config文件中应用了2路SSL。 客户端点是基于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();
    }

我对回调熟练程序,对象状态等有所了解,但有人可以为我进一步说明这一点吗?如何格式化服务的异步部分?网络有很多例子......但都非常令人困惑。我必须对这个概念有一些固有的误解。

编辑: - 我在答案中被告知,服务器端不需要操作异步通信方式。但是我发现了这一点: -

在WCF中实现异步操作 就像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]的操作:

1 个答案:

答案 0 :(得分:1)

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

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

相反,你可以

  1. 在服务合同上,请务必使用[OperationContract(IsOneWay = true)]
  2. 进行装饰
  3. 如果您使用ServiceReference或serviceutil,它将自动创建“传入事件”并为您执行所有客户端异步工作。
  4. 如果您使用的是TCP,也可以创建回调合约,然后在客户端上执行类似的操作 ServiceReference1.IncomingSomething + = new eventHandler。 现在你可以做ServiceReferecnce1.GetSomething(),响应将转到eventhandler函数。
  5. 如果这是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;
                    }
                }