1 ' Copyright (c) Microsoft Corporation. All rights reserved.
4 Imports System
.ServiceModel
5 Imports System
.Threading
8 Imports System
.Globalization
10 Namespace Microsoft
.ServiceModel
.Samples
12 ' Define a service contract.
13 <ServiceContract([Namespace
]:="http://Microsoft.ServiceModel.Samples")> _
14 Public Interface ICalculator
16 <OperationContract()> _
17 Function Add(ByVal n1
As Double, ByVal n2
As Double) As Double
19 <OperationContract()> _
20 Function Subtract(ByVal n1
As Double, ByVal n2
As Double) As Double
22 'Multiply involves some file I/O so we'll make it Async.
23 <OperationContract(AsyncPattern
:=True)> _
24 Function BeginMultiply(ByVal n1
As Double, ByVal n2
As Double, ByVal callback
As AsyncCallback
, ByVal state
As Object) As IAsyncResult
25 Function EndMultiply(ByVal ar
As IAsyncResult
) As Double
27 'Divide involves some file I/O so we'll make it Async.
28 <OperationContract(AsyncPattern
:=True)> _
29 Function BeginDivide(ByVal n1
As Double, ByVal n2
As Double, ByVal callback
As AsyncCallback
, ByVal state
As Object) As IAsyncResult
30 Function EndDivide(ByVal ar
As IAsyncResult
) As Double
34 ' Service class which implements the service contract.
35 <ServiceBehavior(InstanceContextMode
:=InstanceContextMode
.PerCall
, ConcurrencyMode
:=ConcurrencyMode
.Multiple
)> _
36 Public Class CalculatorService
37 Implements ICalculator
39 Public Function Add(ByVal n1
As Double, ByVal n2
As Double) As Double Implements ICalculator
.Add
41 Console
.WriteLine("Received Add Synchronously on ThreadID {0}: Sleeping for 3 seconds", Thread
.CurrentThread
.ManagedThreadId
)
43 Console
.WriteLine("Returning Add Result on ThreadID {0}", Thread
.CurrentThread
.ManagedThreadId
)
48 Public Function Subtract(ByVal n1
As Double, ByVal n2
As Double) As Double Implements ICalculator
.Subtract
50 Console
.WriteLine("Received Subtract Synchronously on ThreadID {0}: Sleeping for 3 seconds", Thread
.CurrentThread
.ManagedThreadId
)
52 Console
.WriteLine("Returning Subtract Result on ThreadID {0}", Thread
.CurrentThread
.ManagedThreadId
)
57 Public Function BeginMultiply(ByVal n1
As Double, ByVal n2
As Double, ByVal callback
As AsyncCallback
, ByVal state
As Object) As IAsyncResult Implements ICalculator
.BeginMultiply
59 Console
.WriteLine("Asynchronous call: BeginMultiply on ThreadID {0}", Thread
.CurrentThread
.ManagedThreadId
)
60 'return an AsyncResult
61 Return New MathAsyncResult(New MathExpression(n1
, n2
, "*"), callback
, state
)
65 Public Function EndMultiply(ByVal ar
As IAsyncResult
) As Double Implements ICalculator
.EndMultiply
67 Console
.WriteLine("EndMultiply called on ThreadID {0}", Thread
.CurrentThread
.ManagedThreadId
)
68 'use the AsyncResult to complete that async operation
69 Return MathAsyncResult
.[End](ar
)
73 Public Function BeginDivide(ByVal n1
As Double, ByVal n2
As Double, ByVal callback
As AsyncCallback
, ByVal state
As Object) As IAsyncResult Implements ICalculator
.BeginDivide
75 Console
.WriteLine("Asynchronous call: BeginDivide on ThreadID {0}", Thread
.CurrentThread
.ManagedThreadId
)
76 'return an AsyncResult
77 Return New MathAsyncResult(New MathExpression(n1
, n2
, "/"), callback
, state
)
81 Public Function EndDivide(ByVal ar
As IAsyncResult
) As Double Implements ICalculator
.EndDivide
83 Console
.WriteLine("EndDivide called on ThreadID {0}", Thread
.CurrentThread
.ManagedThreadId
)
84 'use the AsyncResult to complete that async operation
85 Return MathAsyncResult
.[End](ar
)
89 ' Host the service within this EXE console application.
90 Public Shared
Sub Main()
92 ' Create a ServiceHost for the CalculatorService type.
93 Using serviceHost
As New ServiceHost(GetType(CalculatorService
))
95 ' Open the ServiceHost to create listeners and start listening for messages.
98 ' The service can now be accessed.
99 Console
.WriteLine("The service is ready.")
100 Console
.WriteLine("Press <ENTER> to terminate service.")
110 Public Class MathExpression
112 Private m_n1
As Double
113 Private m_n2
As Double
114 Private m_operation
As String
116 Public Sub New(ByVal n1
As Double, ByVal n2
As Double, ByVal operation
As String)
120 Me.m_operation
= operation
124 Public ReadOnly
Property N1() As Double
134 Public ReadOnly
Property N2() As Double
144 Public ReadOnly
Property Operation() As String
154 Public ReadOnly
Property Result() As Double
158 Select Case Operation
169 Throw
New InvalidOperationException("could not handle " + Operation
+ " operation.")
177 Public Function ToBytes() As Byte()
179 Return Encoding
.Unicode
.GetBytes(String.Format(CultureInfo
.InvariantCulture
, "{0} {1} {2} = {3}", N1
, Operation
, N2
, Result
))
186 ''' Implementation of async Math invocation
188 Class MathAsyncResult
189 Inherits Microsoft
.ServiceModel
.Samples
.TypedAsyncResult(Of
Double)
191 Private fs
As FileStream
192 Private expr
As MathExpression
194 Public Sub New(ByVal mathExpression
As MathExpression
, ByVal callback
As AsyncCallback
, ByVal state
As Object)
195 MyBase
.New(callback
, state
)
197 expr
= mathExpression
198 'Turn the expression into an array of bytes
199 Dim bytes
As Byte() = expr
.ToBytes()
201 'open a file for writing
202 fs
= File
.OpenWrite(Path
.GetRandomFileName() + ".txt")
204 'begin writing asynchronously
205 Dim result
As IAsyncResult
= fs
.BeginWrite(bytes
, 0, bytes
.Length
, New AsyncCallback(AddressOf OnWrite
), Me)
207 'if the write did not complete synchronously, we are done setting up this AsyncResult
208 If Not result
.CompletedSynchronously
Then
212 'If the write did complete synchronously, then we'll complete the AsyncResult
213 CompleteWrite(result
, True)
217 'Completes asynchronous work.
218 'cleans up any resources managed by this AsyncResult
219 'Signals the base class that all work is finished
220 Private Sub CompleteWrite(ByVal result
As IAsyncResult
, ByVal synchronous
As Boolean)
224 'Complete the asynchronous file write
229 'Clean up the file resources
234 'Calling Complete on the base AsyncResult signals the WaitHandle
235 'And makes the callback if necessary
236 MyBase
.Complete(expr
.Result
, synchronous
)
240 Private Sub OnWrite(ByVal result
As IAsyncResult
)
242 'if we returned synchronously, then CompletWrite will be called directly
243 If result
.CompletedSynchronously
Then
247 Console
.WriteLine("IO thread for {0} operation on ThreadID {1}", expr
.Operation
, Thread
.CurrentThread
.ManagedThreadId
)
251 'Call CompleteWrite to cleanup resources and complete the AsyncResult
252 CompleteWrite(result
, False)
256 'if something bad happend, then call the exception overload
257 'on the base class. This will serve up the exception on the
259 MyBase
.Complete(False, e
)