手写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的文章。

你可能感兴趣的:(异步调用)