精华内容
下载资源
问答
  • 会上讨论了具体的业务逻辑,我忽然发现这个WCF服务需要实现的代码中再调用另一个WCF服务。我的妈呀!没遇见过这样的啊! 好吧,想想不是不能够实现,但是还需要具体实贱一下,下面是实践的过程。 如果位大佬...

    昨天项目组开会需要分配一下具体的任务,热后组长分给我一个WCF服务的接口开发,说是内部调用。会上讨论了具体的业务逻辑,我忽然发现这个WCF服务需要在实现的代码中再调用另一个WCF服务。我的妈呀!没遇见过这样的啊!
    好吧,想想不是不能够实现,但是还需要具体实贱一下,下面是实践的过程。
    如果哪位大佬看见了,有好的解决方案可以指教一下。先谢过。
    首先得有俩个WCF服务和寄宿分别是基于http协议的和netTcp协议的。当然协议无关紧要。
    1、第一个服务程序正常写就可以。第一个宿主的配置文件(也是正常的)

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
        <startup> 
            <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
        </startup>
        <system.serviceModel>
          <bindings >
            <netTcpBinding >
              <binding name="nettcp">
               </binding>
            </netTcpBinding>
          </bindings>
          <behaviors>
            <serviceBehaviors>
              <behavior name="beh">
                <serviceDebug includeExceptionDetailInFaults="true"/>
                <serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:2305/"/>
              </behavior>
            </serviceBehaviors>
          </behaviors>
          <services>
            <service name="ConsoleApplication6.Program" behaviorConfiguration="beh">
              <endpoint address="net.tcp://localhost:2303/ConsoleApplication6/Program" binding="netTcpBinding" bindingConfiguration="nettcp" contract="ConsoleApplication6.Interface1" />
    
              <endpoint address="net.tcp://localhost:2303/ConsoleApplication6/Program/mex" binding="mexTcpBinding" contract="IMetadataExchange"/>
    
            </service>
    
          </services>
    
            <client />
    
        </system.serviceModel>
    
    </configuration>

    2、接下来我们的第二个WCF服务的实现代码中要调用第一个WCF服务。
    过程添加服务引用,在代码中实例化一个客户端类然后正常的调用方法如下代码

    public class Service1 : IService1//实现契约接口
        {
            public string GetData(int value)
            {
                return string.Format("You entered: {0}", value);
            }
    
            public CompositeType GetDataUsingDataContract(CompositeType composite)
            {
                if (composite == null)
                {
                    throw new ArgumentNullException("composite");
                }
                if (composite.BoolValue)
                {
                    composite.StringValue += "Suffix";
                }
                return composite;
            }
    
            /// <summary>
            /// 在此实现方法中调用第一个WCF服务
            /// </summary>
            /// <param name="i"></param>
            /// <returns></returns>
            public bool get(int i)
            {
                WcfService1.ServiceReference1.Interface1Client client = new Interface1Client();//WCF服务的客户端实例
                if (i == 1)
    
    
                    return client.get(3);//调用方法
                else
                    return false;
            }
        }

    配置文件也正常如下

    <!-- 以下内容是在system.serviceModel节点中 -->
    <bindings>
          <netTcpBinding>
            <binding name="NetTcpBinding_Interface1" />
          </netTcpBinding>
        </bindings>
        <client>
          <endpoint address="net.tcp://localhost:2303/ConsoleApplication6/Program"
            binding="netTcpBinding" bindingConfiguration="NetTcpBinding_Interface1"
            contract="ServiceReference1.Interface1" name="NetTcpBinding_Interface1">
            <identity>
              <userPrincipalName value="DESKTOP-UO3BIJF\asus" />
    
            </identity>
          </endpoint>
        </client>

    3、然后写第二个wcf服务的寄宿程序,控制台程序,正常编写代码配置文件如下:

    <system.serviceModel>
        <bindings>
          <!--<netTcpBinding>
            <binding name="NetTcpBinding_Interface1" />
          </netTcpBinding>-->
          <wsHttpBinding>
            <binding name="userNameCredentialBinding">
              <security mode="Message">
                <message clientCredentialType="UserName" />
              </security>
            </binding>
          </wsHttpBinding>
        </bindings>
        <services>
          <!-- 注意: 服务名称必须与服务实现的配置名称相匹配。 --><!--行为配置属性是后面的行为中的配置-->
          <service name="WcfService1.Service1" behaviorConfiguration="behaviorConfiguration" >
            <endpoint address="http://localhost:5443/Service1" binding="wsHttpBinding" bindingConfiguration="userNameCredentialBinding"
            contract="WcfService1.IService1"></endpoint>
          </service>
        </services>
        <!--<client>
          <endpoint address="net.tcp://localhost:2303/ConsoleApplication6/Program"
            binding="netTcpBinding" bindingConfiguration="NetTcpBinding_Interface1"
            contract="ServiceReference1.Interface1" name="NetTcpBinding_Interface1">
            <identity>
              <userPrincipalName value="DESKTOP-UO3BIJF\asus" />
            </identity>
          </endpoint>
        </client>-->
    
        <behaviors>
          <!--服务的行为配置 -->
          <serviceBehaviors>
            <behavior name="behaviorConfiguration" >
              <serviceDebug includeExceptionDetailInFaults="true"/>
              <serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:5443/"/>
              <!--以下可以忽略不是关键 -->
              <serviceCredentials>
                <serviceCertificate storeLocation="CurrentUser" storeName="My"  x509FindType="FindBySubjectName" findValue="DESKTOP-UO3BIJF"/>
                <userNameAuthentication userNamePasswordValidationMode="MembershipProvider" membershipProviderName="myProvider"/>
    
              </serviceCredentials>
            </behavior>
          </serviceBehaviors>
        </behaviors>
      </system.serviceModel>

    4、按照我的逻辑这个应该是可以的,宿主成功启动。
    5、编写调用第二个WCF服务的客户端,依然是正常的编写代码,添加服务引用,实例化服务客户端实例。调用服务完成,编译正常。
    6、满心欢喜进行测试,结果
    这里写图片描述
    我返回去第二个WCF服务实现的配置文件中确认了好几遍,明明存在的?
    好吧百度,没有(暂时没找到),仔细想了想,一个大胆的尝试。
    不是第二个服务也寄宿了吗。那我在宿主中再添加一下第一个WCF服务引用,虽然宿主程序不使用代码。如下的配置文件,就是第3步文件中的注释解开。

    <system.serviceModel>
        <bindings>
          <netTcpBinding>
            <binding name="NetTcpBinding_Interface1" />
          </netTcpBinding>
          <wsHttpBinding>
            <binding name="userNameCredentialBinding">
              <security mode="Message">
                <message clientCredentialType="UserName" />
              </security>
            </binding>
          </wsHttpBinding>
        </bindings>
        <services>
          <!-- 注意: 服务名称必须与服务实现的配置名称相匹配。 --><!--行为配置属性是后面的行为中的配置-->
          <service name="WcfService1.Service1" behaviorConfiguration="behaviorConfiguration" >
            <endpoint address="http://localhost:5443/Service1" binding="wsHttpBinding" bindingConfiguration="userNameCredentialBinding"
            contract="WcfService1.IService1"></endpoint>
          </service>
        </services>
        <client>
          <endpoint address="net.tcp://localhost:2303/ConsoleApplication6/Program"
            binding="netTcpBinding" bindingConfiguration="NetTcpBinding_Interface1"
            contract="ServiceReference1.Interface1" name="NetTcpBinding_Interface1">
            <identity>
              <userPrincipalName value="DESKTOP-UO3BIJF\asus" />
            </identity>
          </endpoint>
        </client>
    
        <behaviors>
          <!--服务的行为配置 -->
          <serviceBehaviors>
            <behavior name="behaviorConfiguration" >
              <serviceDebug includeExceptionDetailInFaults="true"/>
              <serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:5443/"/>
              <!--以下可以忽略不是关键 -->
              <serviceCredentials>
                <serviceCertificate storeLocation="CurrentUser" storeName="My"  x509FindType="FindBySubjectName" findValue="DESKTOP-UO3BIJF"/>
                <userNameAuthentication userNamePasswordValidationMode="MembershipProvider" membershipProviderName="myProvider"/>
    
              </serviceCredentials>
            </behavior>
          </serviceBehaviors>
        </behaviors>
      </system.serviceModel>

    好了见证奇迹的时刻:居然居然成功了。
    后记:想了想既然你在宿主程序中可以找到协定。那么在WCF服务实现类中的协定就不重要了吧,试一下,注释掉第2步的配置文件,确保程序编译不报错。
    战战兢兢的运行,TMD居然也成功了。
    结论:在第二个宿主中需要添加对第一个服务的引用。至于其中缘由我目前搞不懂,希望看到的大佬可以解释一下。谢过。

    展开全文
  • //文件的最后也有表单的最后结尾和第一行相同, ////减去末尾的字符串:“\r\n--\r\n” if (firstLine.Contains("--")) ms.SetLength(ms.Length - encoding.GetBytes(firstLine).LongLength - 3 * 2); ...
  • 遇到一个问题,调用服务时,传输的数据多一点时就会出错,从网上找了个篇都是同一个, 设置了一系列的maxXXX和httpRuntime后调试的时候真有效,可是发布后还是有问题,请问还有哪里需要设置的?
  • WCF在不断的进步,4.0下可以很简单的实现无配置WCF,从此不再为大段大段的配置而感到头痛了。 但是,现实是残酷的,项目的.net框架版本不是说变就变的。不过,对于会写代码的人来说,总有办法能绕过这些杂七杂八...

        WCF在不断的进步,在4.0下可以很简单的实现无配置WCF,从此不再为哪大段大段的配置而感到头痛了。

        但是,现实是残酷的,项目的.net框架版本不是说变就变的。不过,对于会写代码的人来说,总有办法能绕过这些杂七杂八的麻烦事情。

        之前的一片文章中已经写了无配置客户端如何实现,但是里面的服务端还是需要配置的,这样还是有少许的不便。所以,今天再来一个完全不用配置文件的WCF测试全套方案不漏——WCF无配置Service端(3.5框架)

        首先,来想一下,WCF需要配置的罪魁祸首是谁?微软,呵呵,确实没错,但是,再具体一点——ServiceHost类。

        就是它要去读取配置,所以,要想实现无配置的WCF服务端,必须从这个类开刀。于是需要修改一下这个类型的某些行为:

       1:      public class SimpleServiceHost
       2:          : ServiceHost
       3:      {
       4:   
       5:          public Uri Uri { get; set; }
       6:          public Binding Binding { get; private set; }
       7:   
       8:          public SimpleServiceHost(Type serviceType,
       9:              Binding binding, Uri uri)
      10:          {
      11:              if (uri == null)
      12:                  throw new ArgumentNullException("uri");
      13:              if (binding == null)
      14:                  throw new ArgumentNullException("binding");
      15:              Uri = uri;
      16:              Binding = binding;
      17:              InitializeDescription(serviceType, new UriSchemeKeyedCollection(uri));
      18:          }
      19:   
      20:          public SimpleServiceHost(object singletonInstance,
      21:              Binding binding, Uri uri)
      22:          {
      23:              if (singletonInstance == null)
      24:                  throw new ArgumentNullException("singletonInstance");
      25:              if (uri == null)
      26:                  throw new ArgumentNullException("uri");
      27:              if (binding == null)
      28:                  throw new ArgumentNullException("binding");
      29:              Uri = uri;
      30:              Binding = binding;
      31:              InitializeDescription(singletonInstance, new UriSchemeKeyedCollection(uri));
      32:          }
      33:   
      34:          protected override ServiceDescription CreateDescription(
      35:              out IDictionary<string, ContractDescription> implementedContracts)
      36:          {
      37:              var result = base.CreateDescription(out implementedContracts);
      38:              foreach (var contract in implementedContracts.Values)
      39:              {
      40:                  var endpoint = new ServiceEndpoint(contract, Binding, new EndpointAddress(Uri.ToString()));
      41:                  endpoint.Name = Binding.Name + "_" + contract.Name;
      42:                  result.Endpoints.Add(endpoint);
      43:              }
      44:              return result;
      45:          }
      46:   
      47:      }

        这个SimpleServiceHost直接继承ServiceHost,然后修改了CreateDescription方法,为契约们增加终结点。

        看到这里,一定会想然后哪?

        不幸的是,这些就是全部的代码了,后面的都是测试代码了,是不是感觉太简单了,就像被忽悠了。是不是被忽悠就直接看测试吧(别忘了上一片文章里面的两个扩展方法):

       1:  [TestMethod]
       2:  public void TestHelloService()
       3:  {
       4:      var uri = new Uri("net.tcp://127.0.0.1:2323/Console/");
       5:      var binding = new NetTcpBinding();
       6:      new SimpleServiceHost(typeof(HelloService), binding, uri).RunWcfService(
       7:          () => uri.InvokeWcfClient<IHelloService>(binding,
       8:              c => Assert.AreEqual("Hello world!", c.Hello("world"))));
       9:  }
      10:   
      11:  [ServiceContract]
      12:  public interface IHelloService
      13:  {
      14:      [OperationContract]
      15:      string Hello(string name);
      16:  }
      17:   
      18:  public class HelloService
      19:      : IHelloService
      20:  {
      21:      public string Hello(string name)
      22:      {
      23:          return "Hello " + name + "!";
      24:      }
      25:  }

        只要这些测试代码,我们的测试就可以跑了。

        如果是实现类实现了多个服务契约会怎么样哪?

       1:  [TestMethod]
       2:  public void TestMultiService()
       3:  {
       4:      var uri = new Uri("net.tcp://127.0.0.1:2323/Multi/");
       5:      var binding = new NetTcpBinding();
       6:      new SimpleServiceHost(typeof(MultiService), binding, uri).RunWcfService(
       7:          () =>
       8:          {
       9:              uri.InvokeWcfClient<IHelloService>(binding,
      10:                  c => Assert.AreEqual("Hello world!", c.Hello("world")));
      11:              uri.InvokeWcfClient<IEchoService>(binding,
      12:                  c => Assert.AreEqual("abc", c.Echo("abc")));
      13:          });
      14:  }
      15:   
      16:  [ServiceContract]
      17:  public interface IEchoService
      18:  {
      19:      [OperationContract]
      20:      string Echo(string message);
      21:  }
      22:   
      23:  public class MultiService
      24:      : IHelloService, IEchoService
      25:  {
      26:      public string Hello(string name)
      27:      {
      28:          return "Hello " + name + "!";
      29:      }
      30:   
      31:      public string Echo(string message)
      32:      {
      33:          return message;
      34:      }
      35:  }

         IHelloService的契约不变,再加个IEchoService,在测试用例中同时测试这两个客户端,可以发现依然正常。

        有了这个类,在单元测试中,就完全可以抛弃WCF的配置文件(正式的运行环境通常还是需要配置在灵活性方面的优势)。

    转载于:https://www.cnblogs.com/vwxyzh/archive/2010/05/14/1735497.html

    展开全文
  • 打开工具的wcf服务配置编辑器,点击文件=》打开=》配置文件(找到你项目所在的app.config配置文件),服务是空的,点击新建服务,浏览找到dll文件单击文件加入服务类型 点击下一步,点击下一步,默认选择http...

    学习wcf,特别是初学者,配置文件很难搞懂,有点复杂,自己手动配置哪有这么多精力啊,这不是吃的太饱了吗,所以学会使用配置编辑器是必须的,下面是学习的流程图。

    打开工具的wcf服务配置编辑器,点击文件=》打开=》配置文件(找到你项目所在的app.config配置文件),服务是空的,在点击新建服务,浏览找到dll文件单击文件加入服务类型

    点击下一步,在点击下一步,默认选择http在下一步,下一步,之后就是下面的页面了,填写好终结点的地址下一步

    完成创建之后便是配置好所谓的ABC了,照着下面的配置就可以了,点击保存。就这样,服务端的配置文件就配置好了,你可以写代码打开服务了

    下面的操作要添加上面配置要的服务,所以还要加上一个服务行为,不然下面客户端是添加不了的,下面给出的httpgeturl便是客户端添加服务引用的地址。

    服务配置就好了

    至于客户端的,直接打开wcf编辑器,新建客户端终结点,配置地址绑定客户端,命名为clientPoint

    当然,客户端还要添加服务引用,运行服务(必须要处于运行状态),把配置好的那个服务地址添加到服务引用

    写好客户端的代码,恭喜恭喜,你毕业了

    转载于:https://www.cnblogs.com/LiuZhen/p/3833712.html

    展开全文
  • 对于下面几种方式,一种是最合适的,我期望的是这样的: ...2) 服务端,调用完毕之后可以尽快释放服务实例(设置的是 [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCal...

    对于下面几种方式,哪一种是最合适的,我期望的是这样的:

    1) 在客户端,对于TCP确保使用连接池,在每一次使用连接之后归还连接等待复用。由于连接池是宝贵的资源,不可能每一次调用都去创建,而是只创建一次。

    2) 在服务端,调用完毕之后可以尽快释放服务实例(设置的是  [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple)])

    3) 对于多线程环境,是线程安全的并且也是高性能的,可以利用多线程环境提高速度的。

    我想了一下有这些写法,每一种测试分别用TCP和HTTP信道运行一遍:

    我分别测试了:

    1) 用ClientBase的方式(也就是添加服务引用后生成的ServiceClient的方式)

    2) 用ChannelFactory方式(直接复用服务契约的方式)

    3) 是否主动开关的区别(主动开关是否会影响性能?是否必要?是否会影响连接的复用?)

    4) 是否共享的区别(共享后是否有性能提高?是否线程安全?)

    Parallel.For(0, it, (i, loopState) =>
    {
         using (ServiceClient client = new ServiceClient(s))
         {
             try
             {

                 if (client.Add(1, 2) != 3) throw new Exception("error");
             }
             catch (Exception ex)
             {
                 Console.WriteLine(ex.ToString());
                 loopState.Break();
             }

         }

    });

    Console.WriteLine(s + " 每次创建 Client:" + sw.ElapsedMilliseconds + "," + it * 1000 / sw.ElapsedMilliseconds);

    2)

    Parallel.For(0, it, (i, loopState) =>
    {
         using (ServiceClient client = new ServiceClient(s))
         {
             client.Open();
             try
             {

                 if (client.Add(1, 2) != 3) throw new Exception("error");
             }
             catch (Exception ex)
             {
                 Console.WriteLine(ex.ToString());
                 loopState.Break();
             }
             client.Close();
         }

    });

    Console.WriteLine(s + " 每次创建 Client (主动开关):" + sw.ElapsedMilliseconds + "," + it * 1000 / sw.ElapsedMilliseconds);

    3)

    using (ServiceClient client = new ServiceClient(s))
    {
         client.Open();
         Parallel.For(0, it, (i, loopState) =>
         {

             try
             {
                 if (client.Add(1, 2) != 3) throw new Exception("error");
             }
             catch (Exception ex)
             {
                 Console.WriteLine(ex.ToString());
                 loopState.Break();
             }
         });
         client.Close();
    }
    Console.WriteLine(s + " 共享 Client:" + sw.ElapsedMilliseconds + "," + it * 1000 / sw.ElapsedMilliseconds);

    4)

    using (ServiceClient client = new ServiceClient(s))
    {
         client.Open();
         Parallel.For(0, it, (i, loopState) =>
         {

             try
             {
                 if (client.Add(1, 2) != 3) throw new Exception("error");
             }
             catch (Exception ex)
             {
                 Console.WriteLine(ex.ToString());
                 loopState.Break();
             }
         });

         client.Close();
    }

    Console.WriteLine(s + " 共享 Client (主动开关):" + sw.ElapsedMilliseconds + "," + it * 1000 / sw.ElapsedMilliseconds);

    5)

    Parallel.For(0, it, (i, loopState) =>
      {
          using (ChannelFactory<IGeneralCalculator> cf = new ChannelFactory<IGeneralCalculator>(s))
          {
              try
              {

                  var client = cf.CreateChannel();

                  if (client.Add(1, 2) != 3) throw new Exception("error");
                  (client as ICommunicationObject).Close();
              }
              catch (Exception ex)
              {
                  Console.WriteLine(ex.ToString());
                  loopState.Break();
              }
          }

      });

    Console.WriteLine(s + " 每次创建 ChannelFactory:" + sw.ElapsedMilliseconds + "," + it * 1000 / sw.ElapsedMilliseconds);

    6)

    Parallel.For(0, it, (i, loopState) =>
    {
         using (ChannelFactory<IGeneralCalculator> cf = new ChannelFactory<IGeneralCalculator>(s))
         {
             cf.Open();
             try
             {

                 var client = cf.CreateChannel();


                 if (client.Add(1, 2) != 3) throw new Exception("error");
                 (client as ICommunicationObject).Close();
             }
             catch (Exception ex)
             {
                 Console.WriteLine(ex.ToString());
                 loopState.Break();
             }

             cf.Close();
         }
        
    });

    Console.WriteLine(s + " 每次创建 ChannelFactory (主动开关):" + sw.ElapsedMilliseconds + "," + it * 1000 / sw.ElapsedMilliseconds);


    7)


    using (ChannelFactory<IGeneralCalculator> cf = new ChannelFactory<IGeneralCalculator>(s))
    {
         Parallel.For(0, it, (i, loopState) =>
         {
             try
             {

                 var client = cf.CreateChannel();

                 if (client.Add(1, 2) != 3) throw new Exception("error");
                 (client as ICommunicationObject).Close();
             }
             catch (Exception ex)
             {
                 Console.WriteLine(ex.ToString());
                 loopState.Break();
             }
         });

    }

    Console.WriteLine(s + " 共享 ChannelFactory:" + sw.ElapsedMilliseconds + "," + it * 1000 / sw.ElapsedMilliseconds);


    8)


    using (ChannelFactory<IGeneralCalculator> cf = new ChannelFactory<IGeneralCalculator>(s))
    {
         cf.Open();
         Parallel.For(0, it, (i, loopState) =>
         {
             try
             {

                 var client = cf.CreateChannel();

                 if (client.Add(1, 2) != 3) throw new Exception("error");
                 (client as ICommunicationObject).Close();
             }
             catch (Exception ex)
             {
                 Console.WriteLine(ex.ToString());
                 loopState.Break();
             }
         });
         cf.Close();
    }

    Console.WriteLine(s + " 共享 ChannelFactory (主动开关):" + sw.ElapsedMilliseconds + "," + it * 1000 / sw.ElapsedMilliseconds);

    测试结果如下(Y坐标是每秒操作执行成功数):

    image

    1) HTTP总体性能比TCP差不少,但是不管哪种方式都差不多,我猜测差不多的原因是因为HTTP是短连接而TCP是长连接的关系。

    2) 按我的想法,每次创建ChannelFactory性能是最差的,可能是每一次都在使用新的连接池,事实也是这样,但是也没有差太多

    3) 我本来以为共享ChannelFactory和每次创建Client的方式性能差不多的(因为ClientBase会缓存ChannelFactory),但是差距还是挺大的

    4) 共享Client方式能有这么高的性能让人意外,我本来以为会和每次创建Client一样,不知这样用会不会有什么问题

    官方的文档中虽然是每次创建Client或ChannelFactory后及时关闭的,但他那个都是控制台程序其实怎么做都不重要,对于ASP.NET多线程环境中的使用究竟哪种最靠谱?

    我个人觉得两种方式比较靠谱的(没看到官方有相关的最佳实践的说法,自己猜的):

    1) 如果使用ClientBase(ServiceClient)方式的,每一次使用都创建,使用后及时关闭

    2) 如果使用ChannelFactory方式的,共享方式使用,但是使用后及时关闭Create出来的Channel

    (反正共享方式即使性能高我是不推荐的,可能会有很多潜在的问题)

    反正不管怎么样,测试结论还是和自己想的不太一样,请大家讨论。

    后记:

    http://blogs.msdn.com/b/wenlong/archive/2007/10/26/best-practice-always-open-wcf-client-proxy-explicitly-when-it-is-shared.aspx

    在此文中,作者的观点是如果希望共享,对于Client方式和ChannelFactory都要显式Open(),否则会在第一次调用后Open,那么一开始的时候可因为排队导致性能变差。

    http://blogs.msdn.com/b/wenlong/archive/2007/10/27/performance-improvement-of-wcf-client-proxy-creation-and-best-practices.aspx

    在此文中,作者的观点是:

    1) 创建ChannelFactory(ClientBase内部也是创建ChannelFactory)是昂贵的,因为需要构建ContractDescription树、反射所有需要的CLR类型、构建信道栈,在.NET 3.5中进行了以下改进:A 在ClientBase内部缓存了ChannelFactory B 改善了信道管理的逻辑,因此不管是使用ClientBase还是直接使用ChannelFactory,性能都有改善

    2) ClientBase对ChannelFactory的缓存采用的是MRU,大小是32。只要InstanceContext、endpointConfiguratioName以及remoteAddress参数匹配上就可以用到缓存。如果不想用到缓存,可以在Open ClientBase之前访问ChannelFactory、Endpoint或是ClientCredentials属性。

    3) 最佳实践是 A 重用ServiceClient能获得最好的性能,但别忘记先Open B 每次都使用新的ServiceClient依靠缓存的话性能也不错 C 共享的话要注意多线程问题

    http://blogs.msdn.com/b/wenlong/archive/2007/11/14/a-sample-for-wcf-client-proxy-pooling.aspx

    作者在此文中给出了Client Proxy Pool的实现,他提到:

    1) 通过客户的反馈我意识到直接重用代理不是理想的,因为可能多线程会出现竞争问题,以及关联的上下文可能会混乱。

    2) 可能使用池的做法更合理,但是需要实现相关的同步、异常处理、无可用对象时新建、池大小可配置等逻辑。

    作者给出了自己的实现,另外我也找到了基于池的一个更完善的动态代理的实现:http://wcfdynamicclient.codeplex.com/

    转载于:https://www.cnblogs.com/lovecindywang/archive/2011/03/17/1987024.html

    展开全文
  • IIS上添加gzip压缩已经不是什么新鲜事情了,但是如何自host的wcf上对rest响应支持gzip压缩? 乍一看这个命题还真的有点难,但是wcf框架本身相当强大,拥有众多的介入点,只要正确的介入binding和behavior...
  • IIS 功能方面提供了最佳选择,尤其是在服务要公开多个系统所依赖的关键业务功能的情形下。如果选择 IIS,就必须选择使用 IIS 6.0 还是 IIS 7.0,由于新的激活功能,显然应当选择后者。需要进程间通信的情形
  • 一、WCF课程介绍 1.1、Web Service会被WCF取代吗? 对于这个问题阿笨的回答是:两者功能特性上却是有新旧之分,但是对于特定的系统,...阿笨的宗旨就是学完此《C#面向服务编程技术WCF从入门到实战演练》课程,让...
  • 使用WCF好处

    2011-09-23 09:24:00
    阐述使用WCF好处 我们为什么选用WCF?...它和别的技术好在,我现在就使用WCF这门技术,我这里就给大家分析一下WCF好处吧。Windows平台下,尤其是.NET平台下开发面向服务的应用程序,或者开发分布...
  • .Net集合是.Net特有的,WCF中不能在服务元数据中公开他们。 定义服务操作时,不管使用种结合接口,他们的传输表现形式都使用了数组。 [ServiceContract] interface IContractManager {...
  • .Net集合是.Net特有的,WCF中不能在服务元数据中公开他们。 定义服务操作时,不管使用种结合接口,他们的传输表现形式都使用了数组。 [ServiceContract] interface IContractManager {...
  • IIS8.5 运行WCF

    2015-12-19 12:08:00
    不过.net这方面还是不错,比java强些,java竟然很多采用自己解析xml方式来做Web服务。难以理解。 但是iis竟然部署wcf比想象中复杂,也算是给我个意外。 步骤 iis8 默认不支持wcf 1 添加mime映射首先添加MIME...
  • 阐述使用WCF好处

    2011-06-01 10:38:00
    它和别的技术好在,我现在就使用WCF这门技术,我这里就给大家分析一下WCF好处吧。Windows平台下,尤其是.NET平台下开发面向服务的应用程序,或者开发分布式系统,最佳选择就是WCF。为什么呢? 原因就在于...
  • 由于项目中用到很多图片,不过现在图片还是由type=file的按钮上传到服务器上,由nginx做静态服务器来访问这些图片,没有用到图片服务器来上传下载,这样做的缺点就是,服务部署哪里,图片就上传到台服务器,没有...
  • 继续Wcf记录点滴

    2019-10-09 04:12:52
    之前说wcf以tcp协议作为通信方式的话会出现很多奇怪的bug,今天我把自己遇到的比较特殊... 出现这种异常属于你的服务端程序出错了,但是又看不见异常源在哪,所以你需要在你的配置文件中添加相应的配置,以便让服务...
  • WCF编程》之错误

    2019-09-23 05:46:29
    不管是服务操作都可能某些时候出现异常,如果处理异常时我们需要关心的问题,良好的编程方式应该是自制的,服务器应该错误发生时捕获它并进行相应处理,异常不应该依靠客户端来进行处理,任何依靠客户端的...

空空如也

空空如也

1 2 3
收藏数 57
精华内容 22
关键字:

wcf服务在哪