我的WCF之旅(1):创建一个简单的WCF程序

STM32硬件I2C死锁问题深度解析与实战解决方案 I2C总线作为一种广泛应用的同步串行通信协议,其核心原理基于主从架构和开漏输出,通过SCL时钟线和SDA数据线实现设备间通信。然而,在实际工程应用中,I2C总线容易因协议状态机异常或物理电平冲突而陷入死锁,导致通信彻底中断,严重影响系统可靠性。针对STM32微控制器,其硬件I2C模块在从机无响应、时钟拉伸超时或MCU意外复位等场景下,极易发生软件状态死锁或物理总线死锁。本文聚焦于**I2C总线死锁**这一常见难题,从超时机制、总线初始化清理、错误恢复等维度,提供一套层次化的**实战解决方案**,帮助开发者构 阅读详情

为了使读者对基于WCF的编程模型有一个直观的映像,我将带领读者一步一步地创建一个完整的WCF应用。本应用功能虽然简单,但它涵盖了一个完整WCF应用的基本结构。对那些对WCF不是很了解的读者来说,这个例子将带领你正式进入WCF的世界。

 

在这个例子中,我们将实现一个简单的计算服务(CalculatorService),提供基本的加、减、乘、除的运算。和传统的分布式通信框架一样,WCF本质上提供一个跨进程、跨机器以及跨网络的服务调用。在本实例中,客户端和服务通过运行在相同的一台机器上进行不同的进程模拟,图1体现了客户端和服务端进程互相调用的关系。

 

 

图1 计算服务应用运行环境

 

WCF的服务不能孤立地存在,需要寄宿于一个运行着的进程中,我们把承载WCF服务的进程称为宿主,为服务指定宿主的过程称为服务寄宿(Service Hosting)。在我们的计算服务应用中,采用了两种服务寄宿方式:通过自我寄宿(Self-Hosting)的方式创建一个控制台应用作为服务的宿主(寄宿进程为Hosting.exe);通过IIS寄宿方式将服务寄宿于IIS中(寄宿进程为IIS的工作进行W3wp.exe)。客户端通过另一个控制台应用模拟(进程为Client.exe)。接下来,我们就一步一步来构建这样的一个WCF应用。

 

步骤一:构建整个解决方案

 

通过VS 2008创建一个空白的解决方案,添加如下四个项目。项目的类型、承载的功能和相互引用关系如下,整个项目在VS下的结构如图2所示。

  • Contracts:一个类库项目,定义服务契约(ServiceContract),引用System.ServiceMode程序集(WCF框架的绝大部分实现和API定义在该程序集中);
  • Services:一个类库项目,提供对WCF服务的实现。定义在该项目中的所有WCF服务实现了定义在Contracts中相应的服务契约,所以Services具有对Contracts项目的引用;
  • Hosting:一个控制台(Console)应用,实现对定义在Services项目中的服务的寄宿,该项目须要同时引用Contracts和Services两个项目和System.ServiceMode程序集;
  • Client:一个控制台应用模拟服务的客户端,该项目引用System.ServiceMode程序集。

 

图2 计算服务在VS中的结构

 

步骤二:创建服务契约

 

WCF采用基于契约的交互方式实现了服务的自治,以及客户端和服务端之间的松耦合。WCF包含四种类型的契约:服务契约、数据契约、消息契约和错误契约,这里着重于服务契约。从功能上讲,服务契约抽象了服务提供的所有操作;而站在消息交换的角度来看,服务契约则定义了基于服务调用的消息交换过程中,请求消息和回复消息的结构,以及采用的消息交换模式。第4章将提供对服务契约的详细介绍。

 

一般地,我们通过接口的形式定义服务契约。通过下面的代码,将一个接口ICalculator定义成服务契约。WCF广泛采用基于自定义特性(Custom Attribtue)的声明式编程模式,我们通过在接口上应用System.ServiceModel.ServiceContractAttribute特性将一个接口定义成服务契约。在应用ServiceContractAttribute特性的同时,还可以指定服务契约的名称和命名空间。至于契约名称和命名空间的含义和作用,在本人拙著《WCF技术剖析(卷1)》第4章,在这里我们将契约名称和命名空间设置成CalculatorService和http://www.artech.com/)。

 

通过应用ServiceContractAttribute特性将接口定义成服务契约之后,接口的方法成员并不能自动成为服务的操作。在此方面,WCF采用的是显式选择(Explicit Opt-in)的策略:我们须要在相应的操作方法上面显式地应用OperationContractAttribute特性。

   1: using System.ServiceModel;
   2: namespace Artech.WcfServices.Contracts
   3: {
   4:     [ServiceContract(Name="CalculatorService", Namespace="http://www.artech.com/")]
   5:     public interface ICalculator
   6:     {
   7:         [OperationContract]
   8:         double Add(double x, double y);
   9:  
  10:         [OperationContract]
  11:         double Subtract(double x, double y);
  12:  
  13:         [OperationContract]
  14:         double Multiply(double x, double y);
  15:  
  16:         [OperationContract]
  17:         double Divide(double x, double y);        
  18:     } 
  19: }
步骤三:创建服务

当服务契约成功创建时,我们需要通过实现服务契约来创建具体的WCF服务。WCF服务CalculatorService定义在Services项目中,实现了服务契约接口ICalculator,实现了所有的服务操作。CalculatorService定义如下:

   1: using Artech.WcfServices.Contracts;
   2: namespace Artech.WcfServices.Services
   3: {
   4:    public class CalculatorService:ICalculator
   5:     {
   6:         public double Add(double x, double y)
   7:         {
   8:             return x + y;
   9:         }
  10:  
  11:         public double Subtract(double x, double y)
  12:         {
  13:             return x - y;
  14:         }
  15:  
  16:         public double Multiply(double x, double y)
  17:         {
  18:             return x * y;
  19:         }
  20:  
  21:         public double Divide(double x, double y)
  22:         {
  23:             return x / y;
  24:         }
  25:     }
  26: }

 

步骤四:通过自我寄宿的方式寄宿服务

 

WCF服务需要依存一个运行着的进程(宿主),服务寄宿就是为服务指定一个宿主的过程。WCF是一个基于消息的通信框架,采用基于终结点(Endpoint)的通信手段。终结点由地址(Address)、绑定(Binding)和契约(Contract)三要素组成,如图3所示。由于三要素应为首字母分别为ABC,所以就有了易于记忆的公式:Endpoint = ABC。一个终结包含了实现通信所必需的所有信息,我们可以这样认识终结点的ABC:

  • 地址(Address):地址决定了服务的位置,解决了服务寻址的问题,《WCF技术剖析(卷1)》第2章提供了对地址和寻址机制的详细介绍;
  • 绑定(Binding):绑定实现了通信的所有细节,包括网络传输、消息编码,以及其他为实现某种功能(比如安全、可靠传输、事务等)对消息进行的相应处理。WCF中具有一系列的系统定义绑定,比如BasicHttpBinding、WsHttpBinding、NetTcpBinding等,《WCF技术剖析(卷1)》第3章提供对绑定的详细介绍;
  • 契约(Contract):契约是对服务操作的抽象,也是对消息交换模式以及消息结构的定义。《WCF技术剖析(卷1)》第4章提供对服务契约的详细介绍。

 

 

图3 终结点三要素

 

服务寄宿的目的就是开启一个进程,为WCF服务提供一个运行的环境。通过为服务添加一个或多个终结点,使之暴露给潜给的服务消费者。服务消费者最终通过相匹配的终结点对该服务进行调用。我们可以完全通过代码的方式完成所有的服务寄宿工作,下面的代码体现了通过一个控制台应用对CalculatorService的寄宿:

   1: using System;
   2: using System.ServiceModel;
   3: using System.ServiceModel.Description;
   4: using Artech.WcfServices.Contracts;
   5: using Artech.WcfServices.Services;
   6: namespace Artech.WcfServices.Hosting
   7: {
   8:     class Program
   9:     {
  10:         static void Main(string[] args)
  11:         {
  12:             using (ServiceHost host = new ServiceHost(typeof(CalculatorService)))
  13:             {
  14:                 host.AddServiceEndpoint(typeof(ICalculator), new WSHttpBinding(), "http://127.0.0.1:9999/calculatorservice");
  15:                 if (host.Description.Behaviors.Find<ServiceMetadataBehavior>() == null)
  16:                 {
  17:                     ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
  18:                     behavior.HttpGetEnabled = true;
  19:                     behavior.HttpGetUrl = new Uri("http://127.0.0.1:9999/calculatorservice/metadata");
  20:                     host.Description.Behaviors.Add(behavior);
  21:                 }
  22:                 host.Opened += delegate
  23:                 {
  24:                     Console.WriteLine("CalculaorService已经启动,按任意键终止服务!");
  25:                 };
  26:  
  27:                 host.Open();
  28:                 Console.Read();
  29:             }
  30:         }
  31:     }
  32: }

WCF服务寄宿通过一个特殊的对象完成:ServiceHost。在上面的例子中,基于WCF服务的类型(typeof(CalculatorService))创建了ServieHost对象,并添加了一个终结点。具体的地址为http://127.0.0.1:9999/calculatorservice,采用了WSHttpBinding,并指定了服务契约的类型ICalculator。

 

松耦合是SOA的一个基本的特征,WCF应用中客户端和服务端的松耦合体现在客户端只须要了解WCF服务基本的描述,而无须知道具体的实现细节,就可以实现正常的服务调用。WCF服务的描述通过元数据(Metadata)的形式发布出来。WCF中元数据的发布通过一个特殊的服务行为ServiceMetadataBehavior实现。在上面提供的服务寄宿代码中,我们为创建的ServiceHost添加了ServiceMetadataBehavior,并采用了基于HTTP-GET的元数据获取方式,元数据的发布地址通过ServiceMetadataBehavior的HttpGetUrl指定。在调用ServiceHost的Open方法对服务成功寄宿后,我们可以通过该地址获取服务相关的元数据。在IE地址栏上键入http://127.0.0.1:9999/calculatorservice/metadata,你将会得到以WSDL形式体现的服务元数据,如图4所示。

 

 

图4 通过HTTP-GET的方式获取WCF服务的元数据

 

在进行真正的WCF应用开发时,一般不会直接通过编码的方式进行终结点的添加和服务行为的定义,而是通过配置的方式进行。上面添加终结点和定义服务行为的代码可以用下面的配置代替:

   1: <?xml version="1.0" encoding="utf-8" ?>
   2: <configuration>
   3:     <system.serviceModel>
   4:         <behaviors>
   5:             <serviceBehaviors>
   6:                 <behavior name="metadataBehavior">
   7:                     <serviceMetadata httpGetEnabled="true" httpGetUrl="http://127.0.0.1:9999/calculatorservice/metadata" />
   8:                 </behavior>
   9:             </serviceBehaviors>
  10:         </behaviors>
  11:         <services>
  12:             <service behaviorConfiguration="metadataBehavior" name="Artech.WcfServices.Services.CalculatorService">
  13:                 <endpoint address="http://127.0.0.1:9999/calculatorservice" binding="wsHttpBinding"                    contract="Artech.WcfServices.Contracts.ICalculator" />
  14:             </service>
  15:         </services>
  16:     </system.serviceModel>
  17: </configuration>

对于初学者来说,WCF的配置显得过于复杂,直接对配置文件进行手工编辑不太现实。在这种情况下,可以直接使用VS提供的配置工具。你可以通过VS的工具(Tools)菜单,选择“WCF Service Configuration Editor”子项,开启这样的一个配置编辑器,如图5所示。

 

如果采用了上诉的配置,服务寄宿代码将会得到极大的精简,只需包含下面几行代码:

   1: namespace Artech.WcfServices.Hosting
   2: {
   3:     class Program
   4:     {
   5:         static void Main(string[] args)
   6:         {
   7:             using (ServiceHost host = new ServiceHost(typeof(CalculatorService)))
   8:             {                
   9:                 host.Opened += delegate
  10:                 {
  11:                     Console.WriteLine("CalculaorService已经启动,按任意键终止服务!");
  12:                 };
  13:  
  14:                 host.Open();
  15:                 Console.Read();
  16:             }
  17:         }
  18:     }
  19: }

 

图5 如何获得WCF服务配置编辑器

 

步骤五:创建客户端调用服务

 

服务被成功寄宿后,服务端便开始了服务调用请求的监听工作。此外,服务寄宿将服务描述通过元数据的形式发布出来,相应的客户端就可以获取这些元数据创建客户端程序进行服务的消费。在VS下,当我们添加服务引用的时候,VS在内部帮我们实现元数据的获取,并借助这些元数据通过代码生成工具(SvcUtil.exe)自动生成用于服务调用的服务代理相关的代码和相应的配置。

 

在运行服务寄宿程序(Hosting.exe)的情况下,右键点击Client项目,在弹出的上下文菜单中选择“添加服务引用(Add Service References)”,如图6所示的添加服务引用的对话会显示出来。在地址栏上键入服务元数据发布的源地址:http://127.0.0.1:9999/calculatorservice/metadata,并指定一个命名空间,点击OK按钮,VS为为你生成一系列用于服务调用的代码和配置。

 

 

图6 添加服务引用

 

在一系列自动生成的类中,包含一个服务契约接口、一个服务代理对象和其他相关的类。被客户端直接用于服务调用的是一个继承自ClientBase<CalculatorService>并实现了CalculatorService接口(CalculatorService为客户端生成的服务契约接口类型)的服务代理类。ClientBase<CalculatorService>的定义如下所示:

   1: namespace Artech.WcfServices.Client.CalculatorServices 
   2: {    
   3:     //其他类型成员
   4:     [System.Diagnostics.DebuggerStepThroughAttribute()]
   5:     [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
   6:     public partial class CalculatorServiceClient : System.ServiceModel.ClientBase<Artech.WcfServices.Client.CalculatorServices.CalculatorService>, Artech.WcfServices.Client.CalculatorServices.CalculatorService {
   7:         
   8:         public CalculatorServiceClient() {
   9:         }
  10:         
  11:         public CalculatorServiceClient(string endpointConfigurationName) : 
  12:                 base(endpointConfigurationName) {
  13:         }
  14:         
  15:         public CalculatorServiceClient(string endpointConfigurationName, string remoteAddress) : 
  16:                 base(endpointConfigurationName, remoteAddress) {
  17:         }
  18:         
  19:         public CalculatorServiceClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) : 
  20:                 base(endpointConfigurationName, remoteAddress) {
  21:         }
  22:         
  23:         public CalculatorServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) : 
  24:                 base(binding, remoteAddress) {
  25:         }
  26:         
  27:         public double Add(double x, double y) {
  28:             return base.Channel.Add(x, y);
  29:         }
  30:         
  31:         public double Subtract(double x, double y) {
  32:             return base.Channel.Subtract(x, y);
  33:         }
  34:         
  35:         public double Multiply(double x, double y) {
  36:             return base.Channel.Multiply(x, y);
  37:         }
  38:         
  39:         public double Divide(double x, double y) {
  40:             return base.Channel.Divide(x, y);
  41:         }
  42: }

我们可以创建CalculatorServiceClient对象,执行相应方法调用服务操作。客户端进行服务调用的代码如下:

   1: using System;
   2: using Artech.WcfServices.Client.CalculatorServices;
   3: namespace Artech.WcfServices.Client
   4: {
   5:     class Program
   6:     {
   7:         static void Main(string[] args)
   8:         {
   9:             using (CalculatorServiceClient proxy = new CalculatorServiceClient())
  10:             {
  11:                 Console.WriteLine("x + y = {2} when x = {0} and y = {1}", 1, 2, proxy.Add(1, 2));
  12:                 Console.WriteLine("x - y = {2} when x = {0} and y = {1}", 1, 2, proxy.Subtract(1, 2));
  13:                 Console.WriteLine("x * y = {2} when x = {0} and y = {1}", 1, 2, proxy.Multiply(1, 2));
  14:                 Console.WriteLine("x / y = {2} when x = {0} and y = {1}", 1, 2, proxy.Divide(1, 2));
  15:             }
  16:         }
  17:     }
  18: }

运行后输出:

x + y = 3 when x = 1 and y = 2
x - y = -1 when x = 1 and y = 2
x * y = 2 when x = 1 and y = 2
x / y = 0.5 when x = 1 and y = 2

客户端通过服务代理对象进行服务的调用,上面的例子通过创建自动生成的、继承自ClientBase<T>的类型对象进行服务调用。实际上,我们还具有另外一种创建服务代理的方法,就是通过ChannelFactory<T>。此外,WCF采用基于契约的服务调用方法,从上面的例子我们也可以看到,VS在进行服务引用添加的过程中,会在客户端创建一个与服务端等效的服务契约接口。在我们的例子中,由于服务端和客户端都是在同一个解决方案中,完全可以让服务端和客户端引用相同的契约。

 

为了演示这种场景,我们将添加的服务引用移除,并为Client项目添加对Contracts项目的引用。借助于这个服务契约,并通过ChannelFactory<ICalculator>创建服务代理对象,直接进行相应的服务调用。下面的代码演示了基于ChannelFacotory<T>进行服务代理的创建和服务调用的方式。

   1: using System;
   2: using System.ServiceModel;
   3: using Artech.WcfServices.Contracts;
   4: namespace Artech.WcfServices.Client
   5: {
   6:     class Program
   7:     {
   8:         static void Main(string[] args)
   9:         {
  10:             using (ChannelFactory<ICalculator> channelFactory = new ChannelFactory<ICalculator>(new WSHttpBinding(), "http://127.0.0.1:9999/calculatorservice"))
  11:             {
  12:                 ICalculator proxy = channelFactory.CreateChannel();
  13:                 using (proxy as IDisposable)
  14:                 {
  15:                     Console.WriteLine("x + y = {2} when x = {0} and y = {1}", 1, 2, proxy.Add(1, 2));
  16:                     Console.WriteLine("x - y = {2} when x = {0} and y = {1}", 1, 2, proxy.Subtract(1, 2));
  17:                     Console.WriteLine("x * y = {2} when x = {0} and y = {1}", 1, 2, proxy.Multiply(1, 2));
  18:                     Console.WriteLine("x / y = {2} when x = {0} and y = {1}", 1, 2, proxy.Divide(1, 2));
  19:                 }
  20:             }
  21:         }
  22:     }
  23: }

由于终结点是WCF进行通信的唯一手段,ChannelFactory<T>本质上是通过指定的终结点创建用于进行服务调用的服务代理。在上面的代码中,在创建ChannelFactory<T>的时候再在构造函数中指定终结点的相关要素(契约通过范型类型表示,地址和绑定则通过参数指定)。在真正的WCF应用中,大都采用配置的方式进行终结点的定义。我们可以通过下面的配置指定终结点的三要素,并为相应的终结点指定一个终结点配置名称(calculatorservice)。

   1: <?xml version="1.0" encoding="utf-8" ?>
   2: <configuration>
   3:     <system.serviceModel>
   4:         <client>
   5:             <endpoint address="http://127.0.0.1:9999/calculatorservice" binding="wsHttpBinding" contract="Artech.WcfServices.Contracts.ICalculator" name="calculatorservice" />
   6:         </client>
   7:     </system.serviceModel>
   8: </configuration>

那么在创建ChannelFactory<T>的时候,就无须再指定终结点的绑定和地址了,而只须制定对应的终结点配置名称。

   1: using System;
   2: using System.ServiceModel;
   3: using Artech.WcfServices.Contracts;
   4: namespace Artech.WcfServices.Client
   5: {
   6:     class Program
   7:     {
   8:         static void Main(string[] args)
   9:         {
  10:             using (ChannelFactory<ICalculator> channelFactory = new ChannelFactory<ICalculator>( "calculatorservice"))
  11:             {
  12:             //省略代码
  13:             }
  14:         }
  15:     }
  16: }

 

步骤六:通过IIS寄宿服务

 

上面演示了通过自我寄宿的方式寄宿服务,现在我们来演示如何将WCF服务寄宿到IIS中。寄宿IIS的服务寄宿比较简单,基本上包含两个步骤:为WCF服务创建.svc文件和创建IIS虚拟目录。

 

1、为WCF服务创建.svc文件

我们知道,每一个ASP.NET Web服务都具有一个.asmx文本文件,客户端通过访问.asmx文件实现对相应Web服务的调用。与之类似,每个WCF服务也具有一个对应的文本文件,其文件扩展名为.svc。基于IIS的服务寄宿要求相应的WCF服务具有相应的.svc文件,.svc文件部署于IIS站点中,对WCF服务的调用体现在对.svc文件的访问上。

.svc文件的内容很简单,仅仅包含一个ServiceHost指令(Directive),该指令具有一个必须的Service属性和一些可选的属性。所以最简单的.svc仅仅具有一个包含Service属性(该属性指明了相应的WCF服务的有效类型)的ServiceHost指令。CalculatorService对应的.svc如下所示,我们把该.svc放在Services项目的根目录下,并将文件命名为CalculatorService.svc。

   1: <%@ServiceHost Service="Artech.WcfServices.Services.CalculatorService"%>

2、为WCF服务创建虚拟目录

和一般的寄宿于IIS下的Web应用一样,需要在IIS下创建相应的虚拟目录。在本应用中,为了方便,我们直接把Services项目的根目录映射为IIS虚拟目录,并把该虚拟目录的命名为WcfServices。

接下来需要为通过IIS寄宿的CalculatorService创建配置文件,我们只须在Services的根目录下创建一个Web.config,将WCF相应的配置添加到该配置文件中即可。Web.config所有配置内容如下所示,可以看出,这基本上和上面通过自我寄宿方式定义的配置一致。唯一不同的是在添加的终结点中无须指定地址,因为.svc所在的地址就是服务的地址。也就是说,CalculatorService的地址为http://127.0.0.1/wcfservices/calculatorservice.svc。你可以通过http://127.0.0.1/wcfservices/calculatorservice.svc?wsdl得到相应的元数据。

   1: <?xml version="1.0" encoding="utf-8" ?>
   2: <configuration>
   3:     <system.serviceModel>
   4:         <behaviors>
   5:             <serviceBehaviors>
   6:                 <behavior name="metadataBehavior">
   7:                     <serviceMetadata httpGetEnabled="true"/>
   8:                 </behavior>
   9:             </serviceBehaviors>
  10:         </behaviors>
  11:         <services>
  12:             <service behaviorConfiguration="metadataBehavior" name="Artech.WcfServices.Services.CalculatorService">
  13:                 <endpoint address="http://127.0.0.1:9999/calculatorservice" binding="wsHttpBinding" contract="Artech.WcfServices.Contracts.ICalculator" />
  14:             </service>
  15:         </services>
  16: </system.serviceModel>
  17: </configuration>

由于在创建Services项目的时候,我们并不曾引用System.ServiceMode程序集,所以须要加上这样一个引用。此外,一个Web应用在运行的时候会默认从位于根目录下的Bin目录加载程序集,而默认的情况下,我们编译后的程序集会自动保存到Bin/Debug|Release目录下,所以须要通过VS修改Services项目属性,将编译输出目录设置成Bin。

 

客户端仅仅须要修改终结点的地址,从而转向对寄宿于IIS下的CalculatorService的访问,该地址即为.svc文件的网络地址:http://127.0.0.1/wcfservices/calculatorservice.svc。

   1: <?xml version="1.0" encoding="utf-8" ?>
   2: <configuration>
   3:     <system.serviceModel>
   4:         <client>
   5:             <endpoint address="http://127.0.0.1/wcfservices/calculatorservice.svc" binding="wsHttpBinding" contract="Artech.WcfServices.Contracts.ICalculator" name="calculatorservice" />
   6:         </client>
   7:     </system.serviceModel>
   8: </configuration>
作者: Artech
出处: http://artech.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
CF登录器易语言源码 一个高防CF登录窗口的易语言源码 高防高防! 立即下载

相关推荐

国产信创服务器软硬件兼容情况1 --- ARM架构

信创,即信息技术应用创新产业,它是数据安全、网络安全的基础,也是新基建的重要组成部分...

一只猿的自我修养 4741

C#创建和部署Windows Service程序

  接下来这里我对Windows Service程序的创建、部署等方面做简单描述。 前言   这里首先有个问题,什么是Windows Service,也就是我们Windows服务。微软的官方定义是这样的:Microsoft Windows 服务(即以前的 NT 服务)使您能够创建在它们自己的 Windows 会话中可长时间运行的可执行应用程序。Windows服务能够随着我们主机开机而自动启动,不显示任何用户界面,可以对服务进行启动、停止、暂停、重启等,是一个后台进程。   通过下面的方法可以查看到我们计算机

耕耘虫 1923

车载导航测试,面试常见问题

车载导航测试是汽车软件测试的重要组成部分,涉及验证导航系统的功能、性能、可靠性和用户体验。在面试中,面试官通常会考察候选人的测试思维、问题解决能力和实际经验。以下我将从常见问题类别入手,逐步介绍面试中的高频问题,并提供结构化分析。通过以上结构化准备,你能在面试中自信应对车载导航测试相关问题。用户体验测试关注界面友好性和交互流畅性,安全测试则涉及功能安全和数据隐私。功能测试聚焦于导航核心功能的正确性,如路线规划、位置定位和地图显示。面试官会考察你如何识别、报告和跟踪缺陷,以及熟悉测试工具。

m0_69889939的博客 527

手把手wcf简单实例

WCF是微软为构建面向服务的应用程序所提供的统一编程模型。 下面通过一个简单的服务示例来认识WCF 1.新建项目,名称 XfServer,解决方案名称 XfStudy,模板选择类库,选择.NET Framework版本 2.修改Class1.cs文件名称为 IFirstService.cs 3.添加引用 System.ServiceModel 4.修改IFirstService.cs代码如下: using System; using System.Collections.Generic; usin.

delphi863的博客 684

Carla-UE4Editor导入RoadRunner地图文件(保姆级教程)

以Carla官网导入RoadRunner地图的标准文档为参考,里面增添了很多细节和注意事项,遇到问题的小伙伴过来看看吧。

DSK_981029的博客 1万+

从零理解Brep:用Python玩转3D建模的边界表示法(附OpenCASCADE示例)

本文深入解析了边界表示法(Brep)在3D建模中的应用,通过Python和OpenCASCADE的实战示例,详细介绍了Brep的核心数据结构、布尔运算、网格转换及3D打印优化技巧。适合CAD设计、3D打印和计算机图形学领域的开发者学习与实践。

n4o5p6q7r的博客 427

C# 使用Get,Post,Soap方式调用WebService

using System; using System.Web; using System.Xml; using System.Collections; using System.Net; using System.Text; using System.IO; using System.Xml.Serialization; //By huangz 2008-3-19 /// /// 利用W

无名剑 3782

在 SAP 世界里拥抱非 SAP 技术:一名 ABAP 开发者的成长路径与实战方法论

那段时间非常煎熬,但它带来的回报也很真实:你会更尊重“可观测性”的价值,也会更愿意在 SAP 场景里把日志、追踪、断言、隔离测试做扎实。解决这类问题,靠的并不是某个神奇的 SAP 函数,而是跨栈的工程设计:接口要有业务幂等键,SAP 侧要有落库与锁策略,返回要有可识别的状态码,异常要能回放,补偿要有可追踪的工单或队列。这套体系吸引我的地方,在于它更贴近真实业务:客户要的往往不是“能打印”,而是“能规范地输出”,包括版式、字体、条码、二维码、电子签章位置、分页规则、多语言、合规水印、可回写的交互字段等。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 168

WCF之旅(1):创建一个简单的WCF程序

为了使读者对基于WCF的编程模型有一个直观的映像,我将带领读者一步一步地创建一个完整的WCF应用。本应用功能虽然简单,但它涵盖了一个完整WCF应用的基本结构。对那些对WCF不是很了解的读者来说,这个例子将带领你正式进入WCF的世界。 在这个例子中,我们将实现一个简单的计算服务(CalculatorService),提供基本的加、减、乘、除的运算。和传统的分布式通信框架一样,WCF本质...

ajian11的专栏 113

SAP_FI模块_固定资产期初导入全流程(含导入代码)

SAP 期初导入资产主数据以及金额相关的操作全流程记录,包含了批导程序的代码,以及错误记录

风沙的博客 1405

RH850从0搭建Autosar开发环境【3X】- Davinci Configurator之EcuM模块配置详解(上)

RH850从0搭建Autosar开发环境【3X】- Davinci Configurator之EcuM模块配置详解(上)

weixin_42412049的博客 1015

转 我的WCF之旅(1):创建一个简单的WCF程序

为了使读者对基于WCF的编程模型有一个直观的映像,我将带领读者一步一步地创建一个完整的WCF应用。本应用功能虽然简单,但它涵盖了一个完整WCF应用的基本结构。对那些对WCF不是很了解的读者来说,这个例子将带领你正式进入WCF的世界。 在这个例子中,我们将实现一个简单的计算服务(CalculatorService),提供基本的加、减、乘、除的运算。和传统的分布式通信框架一 样,WCF本质上...

weixin_30699831的博客 110

openclaw通俗入门系列9——流式传输 + 分块

流式传输 = 不等写完就开始发。分块流式传输是把长回复切成几条消息发(所有渠道),草稿流式传输是像打字一样实时显示(仅 Telegram)。可以配置块大小、发送时机、合并规则、类人延迟。

m0_60605453的博客 506

[原创]我的WCF之旅(1):创建一个简单的WCF程序

写在前面 在Microsoft提出.NET战略以来, 先后推出了一系列产品和技术, 这些产品和技术为我们在.NET平台下建立企业级的分布式应用提供了很大的 便利。这些技术和产品包括:.NET Remoting,XML WebSerivce,WSE(2.0,3.0),Enterprise Service, MSMQ ...... 我们知道,和一个相对独立的应用不同,我们开发一个分布式应用, 尤其...

威尔软件 167

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

上一篇: 《我的WCF之旅》博文系列汇总
下一篇: 我的WCF之旅(2):Endpoint Overview
Csdbfans
博客等级 码龄18年 73粉丝 33原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值