手写WCF异步调用的客户端

       今天想试一下WCF的异步调用的功能,就在一个自己原有的程序上使用。一般情况我都是自己手写代码的,但是这次我看了 张逸的《WCF服务编程》后按照书上的例子编写后发现会抛出一个异常,迫不得已,我只能用svcutil先来生成一个异步的客户端,然后比较代码之前的不同,终于发现问题的所在,现在把代码贴上:
Contracts:
namespace Contracts
{
    [ServiceContract]
    
public interface IAdd
    
{
        [OperationContract]
        
int Add(int x, int y);
    }

}

Services:
namespace Services
{
    
public class AddService :IAdd
    
{
        
public int Add(int x, int y)
        
{
           
return x + y;
        }

    }

}


hosting:
namespace Hosting
{
    
public class CustomValidate : UserNamePasswordValidator
    
{
        
public override void Validate(string userName, string password)
        
{
            Console.WriteLine(userName 
+ " " + password);
            
if (userName != "user" || password != "pwd")
            
{
                Console.WriteLine(
"error");
            }

        }

    }

    
class Program
    
{
        
static void Main(string[] args)
        
{
            
using (ServiceHost host = new ServiceHost(typeof(Services.AddService)))
            
{
                host.Opened 
+= delegate
                
{
                    Console.WriteLine(
"opened");
                   
                }
;
                host.Open();
                Console.Read();
            }

        }

    }

}

Client:

namespace Client
{
    [ServiceContract(ConfigurationName = "Contracts.IAdd")]//问题的坐在,一定不能少

    
public interface IAdd
    
{
        [OperationContract]
        
int Add(int x, int y);
        
        [OperationContract(AsyncPattern 
= true)]
        IAsyncResult BeginAdd(
int x, int y, AsyncCallback callback, object asyncState);
        
int EndAdd(IAsyncResult result);
    }

    
public class AddClient : ClientBase<IAdd>, IAdd
    
{
        
public AddClient() : base() { }
        
public int Add(int x, int y)
        
{
            
return base.Channel.Add(x, y);
        }

        
public IAsyncResult BeginAdd(int x, int y, AsyncCallback callback, object asyncState)
        
{
            
return Channel.BeginAdd(x, y, callback, asyncState);
        }

        
public int EndAdd(IAsyncResult result)
        
{
            
return Channel.EndAdd(result);
        }

    }

    
class Program
    
{
        
static void Main(string[] args)
        
{
            AddClient proxy 
= new AddClient();
            proxy.ClientCredentials.UserName.UserName 
= "user";
            proxy.ClientCredentials.UserName.Password 
= "pwd";
            IAsyncResult asyncResult1 
= proxy.BeginAdd(23nullnull);
           
            
int sum = 0;
            sum 
= proxy.EndAdd(asyncResult1);
            Console.WriteLine(sum);
            proxy.Close();

            Console.Read();
        }

    }

}

Hosting的app.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  
<system.serviceModel>
    
<behaviors>
      
<serviceBehaviors>
        
<behavior name="behavior">
          
<serviceMetadata httpGetEnabled="true" httpGetUrl="http://10.6.235.138:6667/addservice"/>
          
<serviceDebug includeExceptionDetailInFaults="true"/>
          
<serviceCredentials>
            
<clientCertificate>
              
<authentication certificateValidationMode="None"/>
            
</clientCertificate>
            
<serviceCertificate findValue="MyServer" storeLocation="CurrentUser" x509FindType="FindBySubjectName"/>
            
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="Hosting.CustomValidate,Hosting"/>
          
</serviceCredentials>
        
</behavior>
      
</serviceBehaviors>
    
</behaviors>
    
<bindings>
      
<netTcpBinding>
        
<binding name="binding">
          
<security mode="Message">
            
<message clientCredentialType="UserName"/>
          
</security>
        
</binding>
      
</netTcpBinding>
    
</bindings>
    
<services>
      
<service name="Services.AddService" behaviorConfiguration="behavior">
        
<endpoint bindingConfiguration="binding" address="net.tcp://10.6.235.138:6666/addservice" binding="netTcpBinding" contract="Contracts.IAdd"></endpoint>
      
</service>
    
</services>
  
</system.serviceModel>
</configuration>


client的app.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  
<system.serviceModel>
    
<bindings>
      
<netTcpBinding>
        
<binding name="binding2">
          
<security mode="Message">
            
<message clientCredentialType="UserName"/>
          
</security>
        
</binding>
      
</netTcpBinding>
    
</bindings>
    
<client>
      
<endpoint name="point" behaviorConfiguration="behavior3" bindingConfiguration="binding2"  address="net.tcp://10.6.235.138:6666/addservice" binding="netTcpBinding" contract="Contracts.IAdd">
       
<identity>
          
<dns value="MyServer"/>
          
<!-- <certificate encodedValue="c2bb5a41d06ccc2b99bfb771d516728c0af33e78"/>-->
        
</identity>
      
</endpoint>
    
</client>
    
    
<behaviors>
      
<endpointBehaviors>
        
<behavior name="behavior3">
          
<clientCredentials>
            
<serviceCertificate>
              
<authentication certificateValidationMode="None"/>
            
</serviceCertificate>
          
</clientCredentials>
        
</behavior>
      
</endpointBehaviors>
    
</behaviors>
  
</system.serviceModel>
</configuration>

因为是在原有的代码上做的,所以中间涉及到一些安全的部分,该部分请参考Q.yuhen的文章。
原文地址:https://www.cnblogs.com/chenzhou851025/p/1239684.html