Delphi调用WCF异构编程

Delphi调用WCF异构编程

                   老帅

一、项目背景

      几年前,就开始使用Delphi进行分布式开发,最早用的方案是Delphi7+Webservice,在简单的应用场景下,也能够满足需求了。

      喜欢博主的博文,请投出您宝贵的一票,支持一下博主评选博客之星。

      http://vote.blog.csdn.net/blogstaritem/blogstar2013/shuaihj

 

      目前有一个项目,主要的需求点如下:

      1.   有N个系统

      2.   其中有一个系统A为基础数据平台,要为其他系统提供数据服务

      3.   这N个系统中,有用Java开发的Web,有用C#开发的Web,有用Delphi开发的桌面APP,还有用Android开发的手机APP,都要使用系统A提供的基础数据

      4.   系统A虽然要部署在internet上,但是为私有服务,要考虑其安全性。

      5.   系统A要接收多个系统发过来的数据,数据种类将来会有所增加,要保证其可用性和扩展性


      以前曾经测试过Delphi7+WCF的分布式开发架构,但那时Delphi7对WCF支持的不是很好,所以也就没有采用这个架构方案。目前来看如果只是使用Webservice的话,从需求和时间两个维度都不能满足项目的需求。就又想到了WCF,目前我们使用的Delphi版本是DelphiXE3,通过技术预研,我们发现DelphiXE3对WCF有了较好的支持。

二、开发过程

       关于WCF,网上已经有很多介绍的文章,这里就不再展开,直接进入主题,通过一个简单的调用案例,开始我们的Delphi+WCF编程之旅。

       开发环境:VS2013+DelphiXE3
1、为了提供服务,先用VS2013建立一个WCF服务库


1.1确认服务协定IWeatherService

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace WeatherWcfServiceLibrary
{
    [ServiceContract]
    public interface IWeatherService
    {
        // 测试返回简单数据类型
        [OperationContract]
        string GetWeatherDescription(int day);

        // 测试返回复杂数据类型(一定要注意,如果返回的是List,List中不能嵌套List,否则客户端无法识别)
        [OperationContract]
        WeatherData GetWeather(int day);

        // 测试参数回传(一定要注意,回传参数不用用out,否则客户端无法识别)
        [OperationContract]
        void FindWeather(ref WeatherData data);

    }

    [DataContract]
    public class WeatherData
    {
        string description = " ";

        [DataMember]
        public string Description
        {
            get { return description; }
            set { description = value; }
        }
    }
}

 

1.2实现WeatherService服务类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace WeatherWcfServiceLibrary
{
    // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的类名“Service1”。
    public class WeatherService : IWeatherService
    {
        public string GetWeatherDescription(int day)
        {
            return "第" + day.ToString() + "天的天气尚无预测!";
        }

        public WeatherData GetWeather(int day)
        {
            WeatherData weatherData = new WeatherData();
            weatherData.Description = "预告:第" + day.ToString() + "天的天气万里无云!";
            return weatherData;
        }

        public void FindWeather(ref WeatherData data)
        {
            data.Description = "先生:正像你告诉我的,今天的天气真不错!";
        }
    }
}

 

2、为了使用上面的服务类库,需要使用VS2013建立一个WCF宿主程序

 

2.1引用上面的服务类库和必要类库System.ServiceModel


2.2在App.config文件中配置服务

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>

  <system.serviceModel>
    <!--定制服务行为,服务将使用这种行为-->
    <behaviors>
      <serviceBehaviors>
        <behavior name="Laoshuai.WeatherBehavior">
          <!--允许外部获取元数据-->
          <serviceMetadata httpGetEnabled="true"/>
          <!--不包含详细错误信息-->
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>

    <!--定制服务-->
    <services>
      <!--定制服务名称、行为(使用上面定制的行为)-->
      <service name="WeatherWcfServiceLibrary.WeatherService" behaviorConfiguration="Laoshuai.WeatherBehavior">
        <!--定制服务基地址-->
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8801/WeatherService"/>
          </baseAddresses>
        </host>

        <!--定制服务地址(为空则使用上面的基地址)、绑定类型、服务协定-->
        <endpoint address="" binding="basicHttpBinding" contract="WeatherWcfServiceLibrary.IWeatherService"/>

        <!--定制原数据,对外提供服务查找和引用-->
        <endpoint address="mex" binding="basicHttpBinding" contract="IMetadataExchange"/>

      </service>
    </services>
  </system.serviceModel>
</configuration>

2.3启动服务,准备对外提供服务

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.ServiceModel;

namespace WeatherWcfServiceApplication
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // 创建一个宿主对象,使服务能运行在这个宿主中
            ServiceHost host = new ServiceHost(typeof(WeatherWcfServiceLibrary.WeatherService));

            // 打开服务
            if (host.State != CommunicationState.Opening)
            {
                host.Open();

                this.Text = "服务状态:" + host.State;
            }
        }
    }
}

 
2.4程序启动起来以后,测试一下效果


使用浏览器访问:http://localhost:8801/WeatherService

使用浏览器访问:http://localhost:8801/WeatherService?wsdl

将看到以前直接调用WebService时,一样的XML页面

<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:tns="http://tempuri.org/" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" name="WeatherService" targetNamespace="http://tempuri.org/">
<wsdl:types>
<xsd:schema targetNamespace="http://tempuri.org/Imports">
<xsd:import schemaLocation="http://localhost:8801/WeatherService?xsd=xsd0" namespace="http://tempuri.org/"/>
<xsd:import schemaLocation="http://localhost:8801/WeatherService?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/"/>
<xsd:import schemaLocation="http://localhost:8801/WeatherService?xsd=xsd2" namespace="http://schemas.datacontract.org/2004/07/WeatherWcfServiceLibrary"/>
</xsd:schema>
</wsdl:types>
<wsdl:message name="IWeatherService_GetWeatherDescription_InputMessage">
<wsdl:part name="parameters" element="tns:GetWeatherDescription"/>
</wsdl:message>
<wsdl:message name="IWeatherService_GetWeatherDescription_OutputMessage">
<wsdl:part name="parameters" element="tns:GetWeatherDescriptionResponse"/>
</wsdl:message>
<wsdl:message name="IWeatherService_GetWeather_InputMessage">
<wsdl:part name="parameters" element="tns:GetWeather"/>
</wsdl:message>
<wsdl:message name="IWeatherService_GetWeather_OutputMessage">
<wsdl:part name="parameters" element="tns:GetWeatherResponse"/>
</wsdl:message>
<wsdl:message name="IWeatherService_FindWeather_InputMessage">
<wsdl:part name="parameters" element="tns:FindWeather"/>
</wsdl:message>
<wsdl:message name="IWeatherService_FindWeather_OutputMessage">
<wsdl:part name="parameters" element="tns:FindWeatherResponse"/>
</wsdl:message>
<wsdl:portType name="IWeatherService">
<wsdl:operation name="GetWeatherDescription">
<wsdl:input wsaw:Action="http://tempuri.org/IWeatherService/GetWeatherDescription" message="tns:IWeatherService_GetWeatherDescription_InputMessage"/>
<wsdl:output wsaw:Action="http://tempuri.org/IWeatherService/GetWeatherDescriptionResponse" message="tns:IWeatherService_GetWeatherDescription_OutputMessage"/>
</wsdl:operation>
<wsdl:operation name="GetWeather">
<wsdl:input wsaw:Action="http://tempuri.org/IWeatherService/GetWeather" message="tns:IWeatherService_GetWeather_InputMessage"/>
<wsdl:output wsaw:Action="http://tempuri.org/IWeatherService/GetWeatherResponse" message="tns:IWeatherService_GetWeather_OutputMessage"/>
</wsdl:operation>
<wsdl:operation name="FindWeather">
<wsdl:input wsaw:Action="http://tempuri.org/IWeatherService/FindWeather" message="tns:IWeatherService_FindWeather_InputMessage"/>
<wsdl:output wsaw:Action="http://tempuri.org/IWeatherService/FindWeatherResponse" message="tns:IWeatherService_FindWeather_OutputMessage"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="BasicHttpBinding_IWeatherService" type="tns:IWeatherService">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="GetWeatherDescription">
<soap:operation soapAction="http://tempuri.org/IWeatherService/GetWeatherDescription" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="GetWeather">
<soap:operation soapAction="http://tempuri.org/IWeatherService/GetWeather" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="FindWeather">
<soap:operation soapAction="http://tempuri.org/IWeatherService/FindWeather" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="WeatherService">
<wsdl:port name="BasicHttpBinding_IWeatherService" binding="tns:BasicHttpBinding_IWeatherService">
<soap:address location="http://localhost:8801/WeatherService"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

3.使用DelphiXE3调用这个WCF服务

3.1建立一个WinForm程序,引用前面提供的服务

将生成一个服务调用的代理文件WeatherService.pas,源码如下

// ************************************************************************ //
// The types declared in this file were generated from data read from the
// WSDL File described below:
// WSDL     : http://localhost:8801/WeatherService?wsdl
//  >Import : http://localhost:8801/WeatherService?wsdl>0
//  >Import : http://localhost:8801/WeatherService?xsd=xsd0
//  >Import : http://localhost:8801/WeatherService?xsd=xsd2
//  >Import : http://localhost:8801/WeatherService?xsd=xsd1
// Encoding : utf-8
// Version  : 1.0
// (2014-01-08 11:40:10 - - $Rev: 52705 $)
// ************************************************************************ //

unit WeatherService;

interface

uses InvokeRegistry, SOAPHTTPClient, Types, XSBuiltIns;

const
  IS_OPTN = $0001;
  IS_NLBL = $0004;
  IS_REF  = $0080;

type

  // ************************************************************************ //
  // The following types, referred to in the WSDL document are not being represented
  // in this file. They are either aliases[@] of other types represented or were referred
  // to but never[!] declared in the document. The types from the latter category
  // typically map to predefined/known XML or Embarcadero types; however, they could also
  // indicate incorrect WSDL documents that failed to declare or import a schema type.
  // ************************************************************************ //
  // !:string          - "http://www.w3.org/2001/XMLSchema"[Gbl]
  // !:int             - "http://www.w3.org/2001/XMLSchema"[Gbl]

  WeatherData2         = class;                 { "http://schemas.datacontract.org/2004/07/WeatherWcfServiceLibrary"[GblCplx] }
  WeatherData          = class;                 { "http://schemas.datacontract.org/2004/07/WeatherWcfServiceLibrary"[GblElm] }

  // ************************************************************************ //
  // XML       : WeatherData, global, <complexType>
  // Namespace : http://schemas.datacontract.org/2004/07/WeatherWcfServiceLibrary
  // ************************************************************************ //
  WeatherData2 = class(TRemotable)
  private
    FDescription: string;
    FDescription_Specified: boolean;
    procedure SetDescription(Index: Integer; const Astring: string);
    function  Description_Specified(Index: Integer): boolean;
  published
    property Description: string  Index (IS_OPTN or IS_NLBL) read FDescription write SetDescription stored Description_Specified;
  end;

  // ************************************************************************ //
  // XML       : WeatherData, global, <element>
  // Namespace : http://schemas.datacontract.org/2004/07/WeatherWcfServiceLibrary
  // ************************************************************************ //
  WeatherData = class(WeatherData2)
  private
  published
  end;

  // ************************************************************************ //
  // Namespace : http://tempuri.org/
  // soapAction: http://tempuri.org/IWeatherService/%operationName%
  // transport : http://schemas.xmlsoap.org/soap/http
  // style     : document
  // use       : literal
  // binding   : BasicHttpBinding_IWeatherService
  // service   : WeatherService
  // port      : BasicHttpBinding_IWeatherService
  // URL       : http://localhost:8801/WeatherService
  // ************************************************************************ //
  IWeatherService = interface(IInvokable)
  ['{791CBBA3-0C97-0B5E-6A23-77A0CBF082AF}']
    function  GetWeatherDescription(const day: Integer): string; stdcall;
    function  GetWeather(const day: Integer): WeatherData2; stdcall;
    procedure FindWeather(const data: WeatherData2); stdcall;
  end;

function GetIWeatherService(UseWSDL: Boolean=System.False; Addr: string=''; HTTPRIO: THTTPRIO = nil): IWeatherService;

implementation
  uses SysUtils;

function GetIWeatherService(UseWSDL: Boolean; Addr: string; HTTPRIO: THTTPRIO): IWeatherService;
const
  defWSDL = 'http://localhost:8801/WeatherService?wsdl';
  defURL  = 'http://localhost:8801/WeatherService';
  defSvc  = 'WeatherService';
  defPrt  = 'BasicHttpBinding_IWeatherService';
var
  RIO: THTTPRIO;
begin
  Result := nil;
  if (Addr = '') then
  begin
    if UseWSDL then
      Addr := defWSDL
    else
      Addr := defURL;
  end;
  if HTTPRIO = nil then
    RIO := THTTPRIO.Create(nil)
  else
    RIO := HTTPRIO;
  try
    Result := (RIO as IWeatherService);
    if UseWSDL then
    begin
      RIO.WSDLLocation := Addr;
      RIO.Service := defSvc;
      RIO.Port := defPrt;
    end else
      RIO.URL := Addr;
  finally
    if (Result = nil) and (HTTPRIO = nil) then
      RIO.Free;
  end;
end;

procedure WeatherData2.SetDescription(Index: Integer; const Astring: string);
begin
  FDescription := Astring;
  FDescription_Specified := True;
end;

function WeatherData2.Description_Specified(Index: Integer): boolean;
begin
  Result := FDescription_Specified;
end;

initialization
  { IWeatherService }
  InvRegistry.RegisterInterface(TypeInfo(IWeatherService), 'http://tempuri.org/', 'utf-8');
  InvRegistry.RegisterDefaultSOAPAction(TypeInfo(IWeatherService), 'http://tempuri.org/IWeatherService/%operationName%');
  InvRegistry.RegisterInvokeOptions(TypeInfo(IWeatherService), ioDocument);
  { IWeatherService.GetWeatherDescription }
  InvRegistry.RegisterMethodInfo(TypeInfo(IWeatherService), 'GetWeatherDescription', '',
                                 '[ReturnName="GetWeatherDescriptionResult"]', IS_OPTN or IS_NLBL);
  InvRegistry.RegisterParamInfo(TypeInfo(IWeatherService), 'GetWeatherDescription', 'GetWeatherDescriptionResult', '',
                                '', IS_NLBL);
  { IWeatherService.GetWeather }
  InvRegistry.RegisterMethodInfo(TypeInfo(IWeatherService), 'GetWeather', '',
                                 '[ReturnName="GetWeatherResult"]', IS_OPTN or IS_NLBL);
  InvRegistry.RegisterParamInfo(TypeInfo(IWeatherService), 'GetWeather', 'GetWeatherResult', '',
                                '[Namespace="http://schemas.datacontract.org/2004/07/WeatherWcfServiceLibrary"]', IS_NLBL);
  { IWeatherService.FindWeather }
  InvRegistry.RegisterParamInfo(TypeInfo(IWeatherService), 'FindWeather', 'data', '',
                                '[Namespace="http://schemas.datacontract.org/2004/07/WeatherWcfServiceLibrary"]', IS_NLBL);
  RemClassRegistry.RegisterXSClass(WeatherData2, 'http://schemas.datacontract.org/2004/07/WeatherWcfServiceLibrary', 'WeatherData2', 'WeatherData');
  RemClassRegistry.RegisterXSClass(WeatherData, 'http://schemas.datacontract.org/2004/07/WeatherWcfServiceLibrary', 'WeatherData');

end.

3.2引用并调用服务

unit FormWeatherClient;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, WeatherService;

type
  TFrmWeatherClient = class(TForm)
    btn1: TButton;
    edt1: TEdit;
    btn2: TButton;
    edt2: TEdit;
    btn3: TButton;
    edt3: TEdit;
    procedure btn1Click(Sender: TObject);
    procedure btn2Click(Sender: TObject);
    procedure btn3Click(Sender: TObject);
  private
    { Private declarations }
    FWeatherService: IWeatherService;
    function GetWeatherService: IWeatherService;
  public
    { Public declarations }
  end;

var
  FrmWeatherClient: TFrmWeatherClient;

implementation

{$R *.dfm}

procedure TFrmWeatherClient.btn1Click(Sender: TObject);
begin
  edt1.Text := GetWeatherService.GetWeatherDescription(2);
end;

procedure TFrmWeatherClient.btn2Click(Sender: TObject);
var
  data: WeatherData2;
begin
  data := GetWeatherService.GetWeather(2);
  edt2.Text := data.Description;
  data.Free;
end;

procedure TFrmWeatherClient.btn3Click(Sender: TObject);
var
  data: WeatherData2;
begin
  data := WeatherData2.Create;
  GetWeatherService.FindWeather(data);
  edt3.Text := data.Description;
end;

function TFrmWeatherClient.GetWeatherService: IWeatherService;
begin
  if not Assigned(FWeatherService) then
    FWeatherService := WeatherService.GetIWeatherService();

  Result := FWeatherService;
end;

end.

至此,一个DelphiXE3+WCF异构编程的流程就完成了。

源码下载:http://download.csdn.net/detail/shuaihj/6823535

喜欢博主的博文,请投出您宝贵的一票,支持一下博主评选博客之星。

http://vote.blog.csdn.net/blogstaritem/blogstar2013/shuaihj

时间: 2024-09-24 01:23:19

Delphi调用WCF异构编程的相关文章

Delphi中的SQL编程

SQL语言作为关系数据库管理系统中的一种通用的结构查询语言,已经被众多的数据库管理系统所采用,如ORACLE.Sybase.Informix等数据库管理系统,它们都支持SQL 语言.Delphi与使用SQL语言的数据库管理系统兼容,在使用Delphi开发数据库应用程序时,我们可以使用SQL语言编程,支持SQL编程是Delphi的一个重要特征,这也是体现Delphi作为一个强大的数据库应用开发工具的一个重要标志. 17.1 SQL语言简介 17.1.1 SQL的历史 在70年代初,E.E.Codd

WCF服务编程设计规范(6):队列服务、安全和服务总线

WCF服务编程设计规范(6):队列服务.安全和服务总线.本节整理队列服务(Queue Servuce).服务安全(Service Security)和服务总线(Service Bus)的设计规范. Queued Services 队列服务 1. On the client, always verify that the queue (and a dead-letter queue, when applicable) is available before calling the queued s

WCF服务编程设计规范(4):操作与错误设计

WCF服务编程设计规范(4):操作与错误设计.主要包含服务操作与调用.错误设计规范.中英对照.欢迎留言交流.下一节会介绍事务.并发管理和队列服务的内容. Operations and Calls 操作与调用 1. Do not treat one-way calls as asynchronous calls. 不要把单向调用作为异步调用 2. Do not treat one-way calls as concurrent calls. 不要把单向调用作为并发调用 3. Expect exce

ASP.NET中使用HttpWebRequest调用WCF

最近项目需要和第三网站进行数据交换,第三方网站基本都是RESTfull形式的API,但是也有的是Web Service,或者.NET里面的WCF.微软鼓励大家使用WCF替代Web Service. Web Service技术介绍 Web Service是一个平台独立的,松耦合的,自包含的.基于可编程的Web应用程序,可使用开发的XML数据标准来描述.发布.发现.协调和配置这些应用程序,同时用于开发分布式的互操作的应用程序. WCF技术介绍 WCF 是Web Service的升级版本.WCF是Wi

WCF技术剖析之三十一:WCF事务编程[上篇]

WCF事务编程其实很简单,可以用三句话进行概括:通过服务契约决定事物流转(Transaction Flow)的策略:通过绑定实施事务的流转:通过服务行为控制事务的相关行为.本篇文章着重介绍如果通过TransactionFlowAttribute特性定义事务流转策略.  契约时是一种双边协定,是双方就某个关注点达成的一种共识.对于分布式事务的实现来讲,首先需要解决的是事务流转的问题,即事务将客户端的事务流向服务端.要解决事务流转的问题,需要在事务的发送方和接收方就流转问题达成共识,即双方采用相匹配

WCF技术剖析之三十一: WCF事务编程[下篇]

在WCF事务编程模型下,通过服务契约确定事务流转的策略(参阅<上篇>),通过事务绑定实施事务的流转(参阅<中篇>).但是,对于事务绑定接收到并成功创建的事务来说,服务操作的执行是否需要自动登记到该事务之中,以及服务操作采用怎样的提交方式,这就是服务端自己说了算了.正因为如此,WCF通过服务(操作)行为的形式定义事务的登记和提交(完成)方式. 一.事务的自动登记(Enlistment)与提交(完成) 在OperationBehaviorAttribute特性(其本身是一个操作行为)中

《WCF服务编程》关于“队列服务”一个值得商榷的地方

今天写<WCF技术剖析(卷2)>关于"队列服务"部分,看了<WCF服务编程>相关的内容.里面介绍一个关于"终结点不能共享相同的消息队列"说法,个人觉得这值得商榷.撰写此文,希望对此征求大家的意见.[源代码从这里下载] 目录 一."终结点不能共享相同的消息队列" 二.实践出真知 三.为什么同一个服务的终结点可以共享相同的消息队列 四.为什么不同服务的终结点不能共享相同的终结点 一."终结点不能共享相同的消息队列&q

Silverlight同步(Synchronous)调用WCF服务

Silverlight的RIA应用中访问远端的WebService或WCF服务,都是通过异步线程模式调用的.在某些情况下我们的调用是需要同步进行,虽然Silverlight没有内置同步线程模式调用远端服务接口,但是我们可以通过多线程的处理来伪装出同步调用的实现.在.NET Framework的多线程编程中提供了丰富的线程接口,其中AutoResetEvent和ManualResetEvent在多线程编码中最为常用,本文将介绍如何通过AutoResetEvent的线程等待特性实现Silverlig

使用Task简化Silverlight调用Wcf

原文http://www.cnblogs.com/lemontea/archive/2012/12/09/2810549.html 从.Net4.0开始,.Net提供了一个Task类来封装一个异步操作,用来简化异步 方法的调用..Net4.5更进一步,添加了async和await两个关键字,异步编程同步化,不用再写一堆散乱的回调或者完成事件处理. Silverlight5开始支持Task类,但是要用await的话就需要编译器的支持,VS2012直接支持,如果是VS2010,那就要安装Async