Handling multiple requests in a WCF Service

R

Ron

Hi,

I have a WCF service using a WSHTTP binding context running under IIS.

My question specifically is that each request that is processed can
potentially take quite some time to complete (a minute or so)...does the
service by default handle multiple requests simultaneously...or do I need to
implement multithreading in the service to make that happen?

....if so do I implement the multiple threading at then entry point
method...or at which point?

Thank you for any insight you might be able to provide.
Ron
 
P

Peter Morris

It's already multi-threaded. If your jobs are taking that long you might
want to consider segmenting your service from this

DoJob()

to this
StartJob()
CheckProgress()
GetJobResult()


That way you can write the job request to a database and have X threads
processing jobs.
 
N

Nicholas Paldino [.NET/C# MVP]

Ron,

IIS will handle multiple requests simultaneously, as well as the
ServiceHost instance. However, depending on the instancing that you have
set up, it's hard to say. If you are set up for a per-call instancing, then
you don't have to worry, as a new instance of your service object will be
created on each incoming request.

If you are set up as a singleton, then you will have one instance
created for your service at a time, in which case, you have to take into
account the concurrency of the singleton (this would typically be defined
through the ServiceBehaviorAttribute, or through configuration). If you are
not set up for Multiple, then each call will be serialized and be handled
one at a time (although requests will come in on multiple threads and be
queued).
 
R

Ron

Thanks guys good stuff!


How do i know if I am setup to handle multiple"

this is my service web.config:

<?xml version="1.0"?>
<!--
Note: As an alternative to hand editing this file you can use the
web admin tool to configure settings for your application. Use
the Website->Asp.Net Configuration option in Visual Studio.
A full list of settings and comments can be found in
machine.config.comments usually located in
\Windows\Microsoft.Net\Framework\v2.x\Config
-->
<configuration>
<configSections>
<sectionGroup name="system.web.extensions"
type="System.Web.Configuration.SystemWebExtensionsSectionGroup,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35">
<sectionGroup name="scripting"
type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions,
Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="scriptResourceHandler"
type="System.Web.Configuration.ScriptingScriptResourceHandlerSection,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35" requirePermission="false"
allowDefinition="MachineToApplication"/>
<sectionGroup name="webServices"
type="System.Web.Configuration.ScriptingWebServicesSectionGroup,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35">
<section name="jsonSerialization"
type="System.Web.Configuration.ScriptingJsonSerializationSection,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35" requirePermission="false"
allowDefinition="Everywhere"/>
<section name="profileService"
type="System.Web.Configuration.ScriptingProfileServiceSection,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35" requirePermission="false"
allowDefinition="MachineToApplication"/>
<section name="authenticationService"
type="System.Web.Configuration.ScriptingAuthenticationServiceSection,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35" requirePermission="false"
allowDefinition="MachineToApplication"/>
<section name="roleService"
type="System.Web.Configuration.ScriptingRoleServiceSection,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35" requirePermission="false"
allowDefinition="MachineToApplication"/>
</sectionGroup>
</sectionGroup>
</sectionGroup>
</configSections>
<appSettings/>
<connectionStrings>
</connectionStrings>
<system.web>
<!--
Set compilation debug="true" to insert debugging
symbols into the compiled page. Because this
affects performance, set this value to true only
during development.

Visual Basic options:
Set strict="true" to disallow all data type conversions
where data loss can occur.
Set explicit="true" to force declaration of all variables.
-->
<compilation debug="true" strict="false" explicit="true">
<assemblies>
<add assembly="System.Core, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35"/>
</assemblies>
</compilation>
<pages>
<namespaces>
<clear/>
<add namespace="System"/>
<add namespace="System.Collections"/>
<add namespace="System.Collections.Specialized"/>
<add namespace="System.Configuration"/>
<add namespace="System.Text"/>
<add namespace="System.Text.RegularExpressions"/>
<add namespace="System.Linq"/>
<add namespace="System.Web"/>
<add namespace="System.Web.Caching"/>
<add namespace="System.Web.SessionState"/>
<add namespace="System.Web.Security"/>
<add namespace="System.Web.Profile"/>
<add namespace="System.Web.UI"/>
<add namespace="System.Web.UI.WebControls"/>
<add namespace="System.Web.UI.WebControls.WebParts"/>
<add namespace="System.Web.UI.HtmlControls"/>
</namespaces>
<controls>
<add tagPrefix="asp" namespace="System.Web.UI"
assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35"/>
</controls>
</pages>
<!--
The <authentication> section enables configuration
of the security authentication mode used by
ASP.NET to identify an incoming user.
-->
<authentication mode="Forms" />
<!--
The <customErrors> section enables configuration
of what to do if/when an unhandled error occurs
during the execution of a request. Specifically,
it enables developers to configure html error pages
to be displayed in place of a error stack trace.

<customErrors mode="RemoteOnly"
defaultRedirect="GenericErrorPage.htm">
<error statusCode="403" redirect="NoAccess.htm" />
<error statusCode="404" redirect="FileNotFound.htm" />
</customErrors>
-->
<httpHandlers>
<remove verb="*" path="*.asmx"/>
<add verb="*" path="*.asmx" validate="false"
type="System.Web.Script.Services.ScriptHandlerFactory,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35"/>
<add verb="*" path="*_AppService.axd" validate="false"
type="System.Web.Script.Services.ScriptHandlerFactory,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35"/>
<add verb="GET,HEAD" path="ScriptResource.axd"
type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions,
Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
validate="false"/>
</httpHandlers>
<httpModules>
<add name="ScriptModule" type="System.Web.Handlers.ScriptModule,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35"/>
</httpModules>
</system.web>
<system.codedom>
<compilers>
<compiler language="vb;vbs;visualbasic;vbscript" extension=".vb"
warningLevel="4" type="Microsoft.VisualBasic.VBCodeProvider, System,
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<providerOption name="CompilerVersion" value="v3.5"/>
<providerOption name="OptionInfer" value="true"/>
<providerOption name="WarnAsError" value="false"/>
</compiler>
</compilers>
</system.codedom>
<!--
The system.webServer section is required for running ASP.NET AJAX
under Internet
Information Services 7.0. It is not necessary for previous version
of IIS.
-->
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<modules>
<add name="ScriptModule" preCondition="integratedMode"
type="System.Web.Handlers.ScriptModule, System.Web.Extensions,
Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
</modules>
<handlers>
<remove name="WebServiceHandlerFactory-Integrated"/>
<add name="ScriptHandlerFactory" verb="*" path="*.asmx"
preCondition="integratedMode"
type="System.Web.Script.Services.ScriptHandlerFactory,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35"/>
<add name="ScriptHandlerFactoryAppServices" verb="*"
path="*_AppService.axd" preCondition="integratedMode"
type="System.Web.Script.Services.ScriptHandlerFactory,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35"/>
<add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD"
path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35"/>
</handlers>
</system.webServer>
<system.serviceModel>
<services>
<service name="ReportingManagementWebService.ReportingService"
behaviorConfiguration="ReportingManagementWebService.ReportingServiceBehavior">
<!-- Service Endpoints -->
<endpoint address="" binding="wsHttpBinding"
contract="ReportingManagementWebService.IReportingService">
<!--
Upon deployment, the following identity element should be
removed or replaced to reflect the
identity under which the deployed service runs. If removed,
WCF will infer an appropriate identity
automatically.
-->
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding"
contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ReportingManagementWebService.ReportingServiceBehavior">
<serviceAuthorization impersonateCallerForAllOperations="true" />
<!-- To avoid disclosing metadata information, set the value below
to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set
the value below to true. Set to false before deployment to avoid disclosing
exception information -->
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>

this is My .svc file:

Imports System.Runtime.Serialization

Public Class ReportingService
Implements IReportingService

Private m_ReportingServiceMain As ReportingServiceMain = Nothing
Private m_ReportOutput As ReportOutput = Nothing

<OperationBehavior(Impersonation:=ImpersonationOption.Required)> _
Public Function CreateReport(ByVal QueueID As Guid) As ReportOutput
Implements IReportingService.CreateReport
m_ReportingServiceMain = New ReportingServiceMain
Return m_ReportingServiceMain.RunReport(QueueID)
End Function

<OperationBehavior(Impersonation:=ImpersonationOption.Required)> _
Public Function GenerateXML(ByVal QueueID As Guid) As ReportOutput
Implements IReportingService.GenerateXML
Dim strResult As String = ""
m_ReportingServiceMain = New ReportingServiceMain
Return m_ReportingServiceMain.GenerateXML(QueueID)
End Function
End Class

<DataContract()> _
Public Class ReportOutput

<DataMember()> _
Public QueueID As Guid

<DataMember()> _
Public ReportObject As Object

<DataMember()> _
Public Errors As String

<DataMember()> _
Public Debug As String

End Class



Nicholas Paldino said:
Ron,

IIS will handle multiple requests simultaneously, as well as the
ServiceHost instance. However, depending on the instancing that you have
set up, it's hard to say. If you are set up for a per-call instancing,
then you don't have to worry, as a new instance of your service object
will be created on each incoming request.

If you are set up as a singleton, then you will have one instance
created for your service at a time, in which case, you have to take into
account the concurrency of the singleton (this would typically be defined
through the ServiceBehaviorAttribute, or through configuration). If you
are not set up for Multiple, then each call will be serialized and be
handled one at a time (although requests will come in on multiple threads
and be queued).


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Ron said:
Hi,

I have a WCF service using a WSHTTP binding context running under IIS.

My question specifically is that each request that is processed can
potentially take quite some time to complete (a minute or so)...does the
service by default handle multiple requests simultaneously...or do I need
to implement multithreading in the service to make that happen?

...if so do I implement the multiple threading at then entry point
method...or at which point?

Thank you for any insight you might be able to provide.
Ron
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top