Is there a way to configure a WCF Service to create a new Thread to handle any new incoming request?
Yes you can do that - it's called "per-call" handling of requests. The ServiceHost will create a new instance of your service class for each request coming in to handle that one request.
To do this, you need to set your Service class (the one implementing the service interface) to be "PerCall" - you do this by applying an attribute on your service class:
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall)]
public class YourService : IYourService
{
...
}
Marc
Depends on what exactly you want, but the following service behaviour will solve it:
ServiceBehavior:
ConcurrencyMode=ConcurrencyMode.Multiple
InstanceContextMode=InstanceContextMode.Single
Your class will be a singleton, but all calls made to the methods will run in a separate thread. If you need any synchronization though you have to do it manually.
Also don't forget to look into throttling to be aware of potential performance issues.
No, because you would never want to do this. What are you really trying to achieve?
EDIT
Based on more info coming in, here's what I think.
If you just want "sticky state" per request, you should use the state on the Instance and use InstanceContextMode.PerCall, as per marc_s's response.
If you need some state to be in thread-local storage for your call, you can consider using ICallContextInitializer as a way to marshal the state over to the thread that WCF chooses to invoke your method on (and clean the thread state when the call finishes).
But you should not care about "which thread". WCF will handle that with a thread pool on your behalf.
Related
We are creating range of dotnet core 2.0 microservices based on the servicestack framework. We want to use http-header based correlation tokens, so we can track a request in our distributed logging system (Seq).
We would like to use IoC to setup a a class holding a threadsafe JsonServiceClient for performance reasons, but how can we ensure that headers placed on one thread will not leak into another concurrent request? Client code example:
public TResponse Get(IReturn requestDto)
...
_serviceClient.AddHeader("r-id", theReqId); // how can we make these specific for the thread request only?
var responseFromDownstreamService = _serviceClient.Get(requestDto);
If you’re modifying the service client instance the dependency needs to be transient so each thread receives a new instance they can mutate without modifying the same instance used by other threads.
I am new to WCF and am interested what is the best practice to call a service method. The application will consist in a bunch of forms and I would like to know if it's better to declare a global client instance for each form and then just call the methods when needed. Or is it better to instantiate the client proxy before each method call and close it right after.
I believe creating a global var of client for each form will do for you, no need to instantiate service each time before calling the service method.
public MyService ser {get; set;}
Inside class constructor.
ser = new MyService();
The most simple and safest way is constructing client proxy every time you use it.
The drawback of this approach is loosing perfomance, but depending on your binding (http, net.tcp, etc) and service mode (PerCall, Statefull, Singleton) you will not notice the difference (see this answer WCF Proxy Pooling - Is it worth it?).
If you create a proxy on the form level, when this proxy is in the faulted state (because of the connection problems), you won't be able to reuse it and will have to reopen form.
While trying to implement asyncronous email over smtp in my ASP.Net MVC 3 application I've come around SO SmtpClient.SendAsync blocking my ASP.NET MVC Request thread. There I found the article by Phil Haack: The Dangers of Implementing Recurring Background Tasks In ASP.NET which provides a way to avoid crashing of the background thread on AppDomain shutdown.
The article says to call HostingEnvironment.RegisterObject(this); on the constructor and call HostingEnvironment.UnregisterObject(this); only if IRegisteredObject.Stop Method is called.
In a general scenario, when requests arrive permanently, and the scope of the object implementing IRegisteredObject is request, dosn't this approach register objects within each request (utilizing the email functionality) and does not unregister any?
Is it OK? Or should I also unregister after the asynchronous operation completed?
P.S.: as suggested by Damian Edwards in the linked SO question, I use ThreadPool.QueueUserWorkItem to send the email beyond request scope.
I'm not sure what you mean by requests arrive permanently, scope of the object ... is request etc.
Request Scope, permanent, and ThreadPool.QueueUserWorkItem; these words together do not make sense at all. One uses ThreadPool.QueueUserWorkItem so that a request does not take forever. The time-consuming job is done in the background while your request returns immediately as Damian Edwards suggests.
I have used IRegisterObject to send bulk e-mails upon a request received. However, in my case, I have used a singleton object EmailSender that implements IRegisterObject. In that case, it is registered once in the constructor and unregistered once in Stop().
So, in short, please use a singleton.
I want to do something just after my WCF service started. How can do it?
In fact,I should update some variable of my service every 10 minutes. So I put my update code in a thread. But I dont know how start this thread when service started (Is there anything liked Form_Load event in WCF services?)
There is typically no parts of your WCF service that is "just hanging around" in memory ready to do something.... WCF is NOT ASP.NET !
The default setup when hosting in IIS is this:
IIS listens on a specific port/URL for a request - there's not a single trace of your WCF service anywhere in memory
when a first request comes in, IIS will spin up a ServiceHost - a class that can "host" a service
this service host will then look at the request has come in and depending on the target URL, it will decide which service class to instantiate to handle this request. The service class (your service implementation) is then created and the appropriate method on that service class is called and executed, and once that's completed, the service class is disposed
So basically, there are two points where you can hook into:
you could create your own custom ServiceHost class that will do something when it gets instantiated
you can add some "initialization" code to each of your service class methods to handle your needs
It's difficult to keep a thread running on a server. As soon as the last session terminates the application shuts down. Some hosting providers also recycle the app pool on a schedule which kills any chance of keeping a thread running.
That aside, WCF Services don't actually run. They act like web pages triggered by a request. The sensible place to add init code would be in your Application_Start in Global.asax. This would get called once when the application starts (the first request is made).
If you would rather do something on each request to your services, you could hook the Application_BeginRequest event also in Global.asax.
You can create an instanced service, which will call the constructor upon the start of your service:
[ServiceContract]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class InstanceService
{
private int _intValue;
public InstanceService()
{
_intValue = 456;
}
[OperationContract]
public int GetData()
{
return _intValue;
}
}
Invoking GetData() on this service will return an integer with a value of 456.
This can be achieved if you are able to control how to host this. If you can, host your WCF service as a Windows service or an ad hoc executable. Then you can achieve what you want with ease. If you are bound to IIS hosting you must do as others have suggested and handle it per request.
Read up on self hosting wcf if IIS is not required.
I have a WCF service, marked with the OperationContract attribute.
I have a potentially long running task I want to perform when this operation is carried out, but I don't want the caller (in this case Silverlight) to have to wait for that to complete.
What is my best option for this?
I was thinking of either
something like the OnActionExecuted method of ActionFilterAttibute in System.Web.Mvc, but couldn't see an equivilent.
something listening to an event. (The process I want to call is a static, so I'm not too sure about this approach)
something else:
In the scenario I'm working in, I lock the app so the user cannot make any changes during the save until I get the response (a status code) back.
Keep in mind, Silverlight won't actually have to 'wait' for the call to finish. When you create a service reference within Silverlight you will automatically get async calls.
Assuming you really don't need to wait for the call to finish (ie: your service method uses a 'void' return type) you can mark the service method as one-way via:
[OperationContract(IsOneWay = true)]
void MyServiceMethod(some args);
In general, I suggest having another process service handle long-running actions. Create a simple Windows Service, and have it pull requests from an MSMQ queue via WCF. Have the main service post requests to the background service, then return to its caller. If anyone cares about the results, then the results may be placed in an output queue, and the Silverlight application could get them by querying the output queue.
You might also look into Windows Workflow Foundation, which is made to fit very well with WCF. In fact, you can have just this kind of service, where all the logic of the service is in the workflow. If the workflow takes too long, it can be persisted to disk until it's ready to go again.
my suggestion is to go for nettcp binding for your distributed computing
try it and you will get a solution for your problem
for nettcpbinding usage please follow below link
http://msdn.microsoft.com/en-us/library/ff183865.aspx