How to call IsOneWay WCF Service and Properly Close Client

932 Views Asked by At

I'm very new to WCF and I've setup a test website and service. I'm trying two accomplish two things:

  1. Call the service without blocking the user
  2. 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>
1

There are 1 best solutions below

2
On

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