5. WCF 异步调用

原文:http://www.rainsts.net/article.asp?id=432

 

编写步骤:

1. 创建服务契约。

我们为 GetData方法添加了 BeginGetData和 EndGetData两个在 .NET SDK 中 "常见" 的异步操作方法。注意 BeginGetData方法中我们添加了异步声明,而 EndGetData 方法没有。还有就是要注意异步版本方法的参数。

<ServiceContract(SessionMode:=SessionMode.Required)> _
Public Interface IService1

    
<OperationContract()> _
    
Function GetData(ByVal value As IntegerAs String


    
<OperationContract(asyncpattern:=True)> _
    
Function BeginGetData(ByVal value As IntegerByVal callBack As AsyncCallback, ByVal state As ObjectAs IAsyncResult


    
Function EndGetData(ByVal ar As IAsyncResult) As String



End Interface

2. 实现服务契约。

你可能注意到了,我们并没有创建 Add 的委托原型,也没有 "真正" 实现 BeginAdd 和 EndAdd。这是因为消息交换会 "异步" 调用 Add 方法,所有的异步版本方法只是用来创建消息声明而已。

 

Public Class Service1
    
Implements IService1

    
Public Function GetData(ByVal value As IntegerAs String Implements IService1.GetData
        Console.WriteLine(
"服务器方法 GetData 开始执行: {0}", DateTime.Now)
        Debug.WriteLine(
"服务器方法 GetData 开始执行: " & DateTime.Now)
        Thread.Sleep(
5000)
        
Dim str As String = String.Format("You entered: {0}", value)
        Console.WriteLine(
"服务器方法 GetData 执行完成: {0}", DateTime.Now)
        Debug.WriteLine(
"服务器方法 GetData 执行完成: " & DateTime.Now)
        
Return str
    
End Function

    
Public Function BegionGetData(ByVal value As IntegerByVal callback As System.AsyncCallback, ByVal state As ObjectAs IAsyncResult Implements IService1.BeginGetData
        
Throw New Exception("The method or operation is not implemented.")
    
End Function

    
Public Function EndGetData(ByVal ar As System.IAsyncResult) As String Implements IService1.EndGetData
        
Throw New Exception("The method or operation is not implemented.")
    
End Function
End Class

 

客户端调用:

 

    Sub Main()
        
Dim url As String = "http://localhost:8731/Design_Time_Addresses/WcfServiceLibrary1/Service1/mex"
        
Dim host As New System.ServiceModel.ServiceHost(GetType(WcfServiceLibrary1.Service1))
        host.AddServiceEndpoint(
GetType(WcfServiceLibrary1.IService1), New System.ServiceModel.WSHttpBinding, url)
        host.Open()
        Console.WriteLine(host.State.ToString)

        
Dim c = New System.ServiceModel.ChannelFactory(Of WcfServiceLibrary1.IService1)(New System.ServiceModel.WSHttpBinding, url)
        
Dim s = c.CreateChannel
        Console.WriteLine(
"客户端调用 BeginGetData: {0}", DateTime.Now)
        Debug.WriteLine(
"客户端调用 BeginGetData: " & DateTime.Now)
        
Dim ar As IAsyncResult = s.BeginGetData(1New AsyncCallback(AddressOf Print), Nothing)
        Console.WriteLine(
"客户端调用 BeginGetData 完成: {0}", DateTime.Now)
        Debug.WriteLine(
"客户端调用 BeginGetData 完成: " & DateTime.Now)

        
'    Console.WriteLine(s.EndGetData(ar))
        '   Console.WriteLine("客户端调用 EndGetData 完成: {0}", DateTime.Now)

        Console.WriteLine(
"执行完成!")
        Debug.WriteLine(
"执行完成!")
        Console.ReadLine()

    
End Sub

    
Sub Print(ByVal ar As IAsyncResult)
        Console.WriteLine(
"异步执行完成……")
        Debug.WriteLine(
"异步执行完成……")
    
End Sub

 

 

 

 

输出结果:
客户端调用 BeginGetData: 2009-11-23 17:03:34
客户端调用 BeginGetData 完成: 2009-11-23 17:03:34
执行完成!
服务器方法 GetData 开始执行: 2009-11-23 17:03:34
服务器方法 GetData 执行完成: 2009-11-23 17:03:39
异步执行完成……
最后需要注意的是,我们必须使用支持 Session 的 Binding 对象 (BasicHttpBinding 会抛出异常)。

附:其实最简单的办法不是手工添加 AsyncPattern / BeginXXX / EndXXX,而是手工使用 svcutil.exe 生成客户端代理,记住加上 "/async" 参数。不过,我还是觉得写代码爽些!

posted on 2009-11-23 17:09  zqonline  阅读(303)  评论(0编辑  收藏  举报

导航