I have a scenario in which I have to call a WCF Service from VBScript (yes I know this is sad!)
Now I know that when you instantiate a proxy to the service in .Net code, that first call may take 10 to 20 seconds longer as WCF bootstraps the channel between the proxy and the service. Once that is done, all calls through that same proxy are quick. When that proxy is disposed, it seems that WCF keeps that channel open for short while (a minute or 3), because a second instantiation of a proxy and a call to the same service within that time does not carry the same bootstrapping burden...it executes quickly (sub-second response times).
Using VBScript, however, there is no concept of a proxy that gives you a "handle" on the channel...I'm just using ServerXMLHttp objects to send soap packets to the service address.
I can certainly see that the first call takes a good 10 to 20 seconds longer than any subsequent call to the same service, indicating that WCF bootstrapping.
I can also see that WCF timeout of the channel happening, because as long as my VBScript is making calls to the service not more than 2 or so minutes apart, the calls execute quickly. If I wait longer than that between calls, each call seems to cause a bootstrapping of a new WCF channel.
Is there anything I can do to keep that WCF channel open for longer between calls to the service? I'm thinking along the lines of changing the service instancing to PerSession. And I understand that the duration of a session is defined by the length of the life of the proxy (in .Net code). But in VBScript, there is no proxy!? Any idea what defines the length of a WCF Session when using PerSession instancing and calling from VBScript where there is no proxy? Or is there perhaps a way to get a handle on a proxy in VBScript?
Any advice would be appreciated.
Thanks,
Shawn.
Related
I'm developing a UWP client project which need to consume some services of a WCF server. I uses the "add service reference" tool of Visual Studio to auto generate service clients(proxies). The binding type is NetTcpBinding. Below is some code snippet which create the service client:
NetTcpBinding tcpBinding = new NetTcpBinding();
tcpBinding.Security.Mode = SecurityMode.None;
tcpBinding.Security.Transport.ClientCredentialType = TcpClientCredentialType.None;
tcpBinding.Security.Message.ClientCredentialType = MessageCredentialType.None;
MainServiceClient = new MainServiceClient(tcpBinding, new EndpointAddress("net.tcp://localhost:8773/MyWCF/MainService/tcp"));
The question is do I need to call OpenAsync() method of MainServiceClient? It seems the service client can be auto opened when it is first called. But I read from this article that auto-opened service client would have some performance penalty. The article was written in 2007. I just wonder if this mechanism have changed today, especially in UWP project. Can anyone share more light on this topic? Thanks!
To explain this case, you should know three ways to do WCF instance management. WCF has provided three ways by which you can control WCF service instances:Per call, Per session, Single instance.
When we configure a WCF service as per call, new service instances are created for every method call you make via a WCF proxy client.
Very often we need to maintain state between method calls or for a particular session. For those kinds of scenarios, we will need to configure the service per session. In per session, only one instance of a WCF service object is created for a session interaction.
Often we would like to create one global WCF instance for all WCF clients. To create a single instance of a WCF service, we need to configure the WCF service as Single instance mode.
And there are three ways by which you can handle concurrency for each service instance in WCF :single, multiple, and reentrant.
Single: A single request has access to the WCF service object at a given moment of time. So only one request will be processed at any given moment of time. The other requests have to wait until the request processed by the WCF service is completed.
Multiple: In this scenario, multiple requests can be handled by the WCF service object at any given moment of time. In other words, requests are processed at the same time by spawning multiple threads on the WCF server object. So you have great throughput here but you need to ensure concurrency issues related to WCF server objects.
Reentrant: A single request thread has access to the WCF service object, but the thread can exit the WCF service to call another WCF service or can also call a WCF client through callback and reenter without deadlock.
In "Instance mode = Per Session and Concurrency = Single" combination, one WCF service instance is created for every WCF client session because the WCF instance mode is set to per session. All the method are executed in a sequential manner one by one. In other words, only one thread is available for all method calls for a particular service instance.
For the above scenario, you should always open WCF client proxy explicitly before you are making any calls. Because it will maintain service state between method calls and obtain high performance.
For more detail you could refer to "WCF Concurrency (Single, Multiple, and Reentrant) and Throttling" and "Three ways to do WCF instance management".
I currently have an application whereby a user makes a request to my ASP.Net UI, which in turns makes an async call into a WCF service to keep the ASP.net thread free.
The WCF service is essentially a translation module, sat on the restricted network, and bridging the DMZ to the Trusted network. This service calls out to a Java service, which will hit the DB, and I currently have this as a synchronous call.
My WCF services are setup with ConcurrencyMode.Single, and InstanceContextMode.PerCall, so I guess that when I run out of threads on the service host, I'll start backing up requests because the UI is calling async, allowing the user to send multiple requests.
Should I be calling the Java service as an async task, like I do in the UI?
async-await is almost always a good idea. It doesn't really matter which IO you are using (in this case a network call to a java service) as long as it can benefit from treating it as an asynchronous by releasing threads while waiting for IO to complete.
Of course you would get a bigger benefit by also making the java service fully asynchronous, but it isn't necessary.
I have just inherited an asp.net mvc 3 site operating on .net 4 which makes heavy use of WCF calls to a very slow external service. The site is not yet live.
One curious piece of code I've found is around the WCF client proxy usage. There is one instance created for the entire aspnet application which is shared between all threads. So, effectively a global variable.
To me, this screams danger yet the site operates without error even under load testing. There is no guard code preventing concurrent calls on the WCF client in the site.
Can someone confirm the safety of using what is essentially a singleton WCF proxy in an asp net app? Wouldn't faulting kill the proxy for all threads?
Can someone confirm the safety of using what is essentially a
singleton WCF proxy in an asp net app? Wouldn't faulting kill the
proxy for all threads?
The proxy is thread safe but as you say, it should be handled with care because it could be in a faulted state in which case the channel should be opened again. You may take a look at the following sample implementation that I have been using to reuse the same channel factory. What is expensive is the creation of the channel factory, not the channel itself.
I have to create a WCF web service that proxies an IMAP service (so that it can be consumed by a SL application).
The IMAP service requires that first the Login(credentials) method is called, to authenticate with the IMAP server. After the Login method is called the connection is kept open and other operations can be performed.
Does anybody know how can achieve this with a WCF service?
One solution I want to avoid is the proxy to login for every operation it has to perform (as the login operation usually takes 1-2 seconds). And I would have to pass the credentials every time: GetMail(credentials), GetFolders(credentials), etc.
I know it is highly recommended that WCF services not to be stateful, but it seems I need to keep the state of IMAP connection for every client. How can I do this?
Thanks!
This is one of those rather rare cases where I think using WCF sessions makes sense:
your first call that calls the IMAP Login method starts a WCF session
any subsequent call will be using the same session
some final call (e.g. something like a Done or Logout) will terminate that session
With a session in WCF, your service class on the server stays in memory for the duration of the entire session, i.e. it's not constantly re-created, and thus you can keep the IMAP connection "live" inside your service class.
Resources:
Sessions, Instancing, and Concurrency (MSDN)
Using Sessions (MSDN)
WCF Sessions - a brief introduction
WCF Sessions
Per-Session Instance Management in WCF
Be aware: WCF sessions are NOT ASP.NET sessions - those are two totally different things! Just to be clear from the get-go.
Also: only a handful of WCF bindings support sessions - netTcpBinding, wsHttpBinding and netNamedPipeBinding (as far as I know)
I have a WCF service hosted as Windows Service with most of its methods currently defined as:
[OperationContract(IsOneWay = true)]
But, now I need to send response back to the calling Web application for these service methods.
Now, because service methods are bit heavy (FYI, they are reporting methods that needs to do mail merge for a no. of records), I am thinking to either queue them or to process asynchronously, so essentially when the request is sent to the service it should save the request to database/queue, returning Request-Id to calling Web application.
In the mean-time, WCF service can just process incompleted requests from the queue or database.
Then either calling Web application can ping WCF service for status of request because it has Request-Id or
WCF service can ping back to calling app when the process corresponding to a Request-Id is completed.
To achieve above, can anyone please guide what changes I need to make to my WCF service (which currently has all one way operation)?
Also, please guide me whether I need to go for Asynch operation or message queuing?
Thank you!
Of course, going Async is simple:
remove the OneWay on the OperationContract in question and regenerate your Service WITH Async methods. There's a reason why Silverlight forces you to use Async operations. They do force you to rethink your UI.