I'm very new to WCF and I've setup a test website and service. I'm trying two accomplish two things:
- Call the service without blocking the user
- Close the client properly
I created a webservice and gave it the isoneway attribute. I've managed to call it without blocking the user but I'm worried that I'm not closing the client. How can I call this service without blocking the user and still close the client properly? Should I use the async method (TestServiceAsync)? Should I use the BeginXX, EndXX methods?
Client:
Dim callservice As New WCFEmailServices.EmailServiceClient()
callservice.TestService()
callservice.Close()
Webservice:
<ServiceContract()> _
Public Interface IEmailService
<OperationContract(IsOneWay:=True)> _
Sub TestService()
End Interface
Public Class EmailService
Implements IEmailService
Public Sub TestService() Implements IEmailService.TestService
Dim srvBody As String = ""
srvBody = "START: " + DateTime.Now.ToLongTimeString() + System.Environment.NewLine
Thread.Sleep(10000)
srvBody += "END: " + DateTime.Now.ToLongTimeString() + System.Environment.NewLine
Me.SendEmail("[email protected]", "test", srvBody, Nothing)
End Sub
Function SendEmail(ByVal srpTo As String, ByVal srpSubject As String, ByVal srpBody As String, ByVal srpAttachmentPath As String) As Boolean
Dim MailMsg As New MailMessage(New MailAddress("[email protected]"), New MailAddress(srpTo))
MailMsg.BodyEncoding = Encoding.UTF8
MailMsg.Subject = srpSubject
MailMsg.Body = srpBody
MailMsg.IsBodyHtml = True
If srpAttachmentPath IsNot Nothing Then
Dim srvAttachment As New Attachment(srpAttachmentPath)
MailMsg.Attachments.Add(srvAttachment)
End If
Dim SmtpMail As New SmtpClient("smtp.gmail.com", 587)
SmtpMail.UseDefaultCredentials = False
SmtpMail.EnableSsl = True
SmtpMail.Credentials = New System.Net.NetworkCredential("No_Reply@test", "password")
Try
SmtpMail.Send(MailMsg)
Catch
Return False
End Try
Return True
End Function
End Class
WebConfig:
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IEmailService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text"
textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Message">
<transport clientCredentialType="Windows" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true"
algorithmSuite="Default" establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:61450/EmailService.svc" binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IEmailService" contract="WCFEmailServices.IEmailService"
name="WSHttpBinding_IEmailService">
<identity>
<servicePrincipalName value="host/localhost" />
</identity>
</endpoint>
</client>
<services>
<service behaviorConfiguration="WCFService.Service1Behavior"
name="WCFService.Service1">
<endpoint address="" binding="wsHttpBinding" contract="WCFService.IService1">
<identity>
<servicePrincipalName value="host/localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
<service behaviorConfiguration="ClientWebApp.EmailServiceBehavior"
name="ClientWebApp.EmailService">
<endpoint address="" binding="wsHttpBinding" contract="ClientWebApp.IEmailService">
<identity>
<servicePrincipalName value="host/localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WCFService.Service1Behavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
<behavior name="ClientWebApp.EmailServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
You are properly closing the client after the IsOneWay call. Based upon your binding, the close() is blocking until the IsOneWay completes.
You can find more information here: Calling Close() on Service Proxy blocks after One Way WCF call
and from this blog within the answer: WCF Best Practice #5