wcf service stop responding i think it because the application is not closing connactions to wcf - wcf

this is not my wcf service but i would like to fix it
i need second opinion
here is the code of opening the service from silverlight
i can not put all the code because the project is very big
i just do not see in all the project a m_MdxService.close()
and i think problem off randomly the wcf stop responding
and the only thing fixing it is recycling appication pool
is because the silverlight is not closing the wcf object .
the wcf service is running on it own application pool . the server is 64 bit
public abstract class CubeControl : Control, IFilter
{
protected MdxClient m_MdxService;
protected GeneralClient m_GeneralService;
protected PortalClient m_PortalService;
protected ListsSoapClient m_PortalListsService;
public GraphControl(string cubeName, SharedContract.Filters filter)
: base(cubeName)
{
AttachEvents();
Init(filter);
}
public override void UpdateGraph()
{
flipable.Visibility = Visibility.Collapsed;
progressStackPanel.Visibility = Visibility.Visible;
noDataStackPanel.Visibility = Visibility.Collapsed;
DataPointEventArgs dpe;
switch (m_DrillLevel)
{
case 0:
m_MdxService.GetGraphDataAsync(SharedContract.Enums.Query.NumberOfEmployees, Filter, null, null);
break;
case 1:
dpe = m_DrillParam as DataPointEventArgs;
m_MdxService.GetGraphDataAsync(SharedContract.Enums.Query.NumberOfEmployeesYears, Filter, dpe.Key, null);
break;
case 2:
dpe = m_DrillParam as DataPointEventArgs;
string temp = selectedYear + "," + dpe.Key.ToString();
m_MdxService.GetGraphDataAsync(SharedContract.Enums.Query.NumberOfEmployeesMonth, Filter, temp, null);
break;
}
}
void InitServices()
{
m_MdxService = new MdxClient();
m_MdxService.InnerChannel.OperationTimeout = new TimeSpan(0, 4, 0);
m_GeneralService = new GeneralClient();
m_GeneralService.InnerChannel.OperationTimeout = new TimeSpan(0, 4, 0);
m_PortalService = new PortalClient();
m_PortalService.InnerChannel.OperationTimeout = new TimeSpan(0, 4, 0);
m_PortalListsService = new ListsSoapClient();
m_PortalListsService.InnerChannel.OperationTimeout = new TimeSpan(0, 4, 0);
}
void AttachEvents()
{
m_MdxService.GetGraphDataCompleted += new EventHandler<GetGraphDataCompletedEventArgs>(m_MdxService_GetGraphDataCompleted);
}
void m_MdxService_GetGraphDataCompleted(object sender, GetGraphDataCompletedEventArgs e)
{
GetGraphDataCompleted(sender, e);
GetDataCompleted(this);
}
}

Instead of creating the client withing the control why not have a central access and creating point for the service proxy withing your silverlight client.
Eg. On the application class of your silverlight app add a member MdxService of type "proxy". Then at application startup time configure the binding and endpoint and create the instance.
Then within your control access it using App.Current.MdxService.GetGraphDataAsync also register for the completed event with App.Current.MdxService..GetGraphDataCompleted.
That way you have one instance of your service client.
I do however think that your issue runs deeper and you need to find the root cause.If the application pool needs recycling there definitely some other cause in my mind. Have a look at the size of your workingset on the server hosting the service. It might be that api has causing memory issues. If its around 900MB and appPool is running in 32bit mode you have a problem on server if 64bit mode it will be able to handle much more tho.
maybe think about running that service separately. In its own application pool and compile and deploy it separately.
Hope helps
Cheers

Related

How to increase the timeout values for a WCF service in a dot net core 2.1 project

I am posting this because I was unable to find any place on Stack Overflow that addresses this issue for a .Net-Core project utilizing WCF by adding the service reference through Connected Services.
My issue was that I was facing client side timeouts because of long running operation requests.
So, how does one increase the timeout values for the wcf client objects since .Net-Core no longer uses the web config to store the configuration values for the WCF service references? (Please see my provided answer)
Under Connected Services in Solution Explorer, after adding a WCF service, a few files are generated for that service. You should see a folder with the name you gave the WCF service reference and under that a Getting Started, ConnectedService.json and a Reference.cs file.
To increase any of the client service object's timeout values, open Reference.cs and locate method: GetBindingForEndpoint
Inside this method you should see something like this:
if ((endpointConfiguration == EndpointConfiguration.BasicHttpBinding_IYourService))
{
System.ServiceModel.BasicHttpBinding result = new System.ServiceModel.BasicHttpBinding();
result.MaxBufferSize = int.MaxValue;
result.ReaderQuotas = System.Xml.XmlDictionaryReaderQuotas.Max;
result.MaxReceivedMessageSize = int.MaxValue;
result.AllowCookies = true;
//Here's where you can set the timeout values
result.SendTimeout = new System.TimeSpan(0, 5, 0);
result.ReceiveTimeout = new System.TimeSpan(0, 5, 0);
return result;
}
Just use result. and the timeout you want to increase like SendTimeout, ReceiveTimeout, etc. and set it to a new TimeSpan with the desired timeout value.
I hope this proves to be a useful post to someone.
Answer by Ryan Wilson will work but only until you will try to update service. Reference.cs will be overwritten.
In .NET Core 3.1 you can grammatically modify binding timeouts:
public MemoqTMServiceClass(string api_key)
{
client = new TMServiceClient();
var eab = new EndpointAddressBuilder(client.Endpoint.Address);
eab.Headers.Add(
AddressHeader.CreateAddressHeader("ApiKey", // Header Name
string.Empty, // Namespace
api_key)); // Header Value
client.Endpoint.Address = eab.ToEndpointAddress();
client.Endpoint.Binding.CloseTimeout = new TimeSpan(2, 0, 0);
client.Endpoint.Binding.OpenTimeout = new TimeSpan(2, 0, 0);
client.Endpoint.Binding.ReceiveTimeout = new TimeSpan(0, 10, 0);
client.Endpoint.Binding.SendTimeout = new TimeSpan(0, 10, 0);
}
Just implement the following partial method in the generated proxy class to configure the service endpoint. Place the partial method in your own file to make sure it will not be overwritten.
static partial void ConfigureEndpoint(System.ServiceModel.Description.ServiceEndpoint serviceEndpoint, System.ServiceModel.Description.ClientCredentials clientCredentials);

WCF EndpointNotFoundException

I am working on a simple WCF service, MiniCalcService which has only one operation Add. The client and host are both console applications. The client application takes in the operands necessary for each operation and passes them over to the service. The service returns the result which would be displayed on the client console.
Host is running
I am doing everything in code so far and there is no app.config.
There is no large data being passed, just two or three numbers
This worked for me yesterday. Today when I tried the same thing, it throws the following exception:
There was no endpoint listening at http://localhost:8091/MiniCalcService that could accept the message.
Here is the Stack Trace. Not that it might matter, but MiniCalcClient is developed in Visual Studio and MiniCalcService and MiniCalcHost are developed in SharpDevelop.
MiniCalcHost:
using(ServiceHost host = new ServiceHost(typeof(MiniCalcService.Service), new Uri("http://localhost:8091/MiniCalcService")))
{
host.AddServiceEndpoint(typeof(MiniCalcService.IService),new BasicHttpBinding(),"Service");
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
host.Description.Behaviors.Add(smb);
host.Open();
Console.WriteLine("Serving MiniCalcService since {0}", DateTime.Now);
Console.Write("Press ENTER key to terminate the MiniCalcHost . . . ");
Console.ReadKey(true);
}
MiniCalcClient:
static string Calculator(string operation, params string[] strOperands)
{
EndpointAddress ep = new EndpointAddress("http://localhost:8091/MiniCalcService");
IService proxy = ChannelFactory<IService>.CreateChannel(new BasicHttpBinding(), ep);
int[] operands;
string result = string.Empty;
try { operands = Array.ConvertAll(strOperands, int.Parse); }
catch (ArgumentException) { throw; }
switch (operation)
{
case "add":
result = Convert.ToString(proxy.Add(operands));//<---EXCEPTION
break;
default:
Console.WriteLine("Why was this reachable again?");
break;
}
return result;
}
Service Contract IService:
[ServiceContract(Namespace="learning.wcf.MiniCalc")]
public interface IService
{
[OperationContract]
double Add(params int[] operands);
}
Can you please help me identify what's causing this exception?
Solution: I changed this line:
EndpointAddress ep = new EndpointAddress("http://localhost:8091/MiniCalcService");
to this:
EndpointAddress ep = new EndpointAddress("http://localhost:8091/MiniCalcService/Service");
and it worked.
I'm not sure if you can use the params in a WCF service call.... seems unnecessary, anyway....
Could you try these two service contracts instead, just to see if those would work:
[ServiceContract(Namespace="learning.wcf.MiniCalc")]
public interface IService2
{
[OperationContract]
int Add(int op1, int op2);
}
and
[ServiceContract(Namespace="learning.wcf.MiniCalc")]
public interface IService3
{
[OperationContract]
int Add(List<int> operands);
}
I'm just wondering if removing the params from your service contract might make it run - everything seems fine at first glance...
OK, so it wasn't this first attempt ......
Well - quite obvious, really: you're using a using block around the service host instantiation:
using(ServiceHost host = new ServiceHost(typeof(MiniCalcService.Service), new Uri("http://localhost:8091/MiniCalcService")))
{
host.AddServiceEndpoint(typeof(MiniCalcService.IService),new BasicHttpBinding(),"Service");
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
host.Description.Behaviors.Add(smb);
host.Open();
Console.WriteLine("Serving MiniCalcService since {0}", DateTime.Now);
Console.Write("Press ENTER key to terminate the MiniCalcHost . . . ");
}
So by the time the code reaches the closing bracket }, the ServiceHost instance will be disposed and thus the service host closed. There's no running service host anymore!
You need to stop the code execution somewhere after the call to host.Open() by e.g.
Console.ReadLine();
or something else.
So your first claim that Host is running really doesn't hold up - it's running briefly and then is terminated again right away.....

Providing workflow extensions to a workflow service - WF 4.0

Greetings one and all!
I'm new to WF 4.0 and WWF in general so forgive me if this seems like a newbie type of question, but believe me I've scoured the depths of the Internet for a solution to this problem, but to no avail.
I have created a sample WF application with a custom CodeActivity that requires an extension be provided, as per below:
public sealed class PreparePizza : CodeActivity
{
public InArgument<Order> Order { get; set; }
protected override void CacheMetadata(CodeActivityMetadata metadata)
{
base.CacheMetadata(metadata);
if (this.Order == null)
metadata.AddValidationError("You must supply an Order.");
metadata.RequireExtension<IPreparePizzaExtension>();
}
// If your activity returns a value, derive from CodeActivity<TResult>
// and return the value from the Execute method.
protected override void Execute(CodeActivityContext context)
{
// Obtain the runtime value of the Text input argument
Order order = context.GetValue(this.Order);
var extension = context.GetExtension<IPreparePizzaExtension>();
extension.Prepare(order);
}
}
public interface IPreparePizzaExtension
{
void Prepare(Order order);
}
I then slot this activity into a workflow service and attempt to consume via my web app by adding a service reference. However, when I add the reference I get:
System.Activities.ValidationException: An extension of type 'PizzaMan.ActivityLibrary.IPreparePizzaExtension' must be configured in order to run this workflow.
Fair enough - of course my activity requires that I pass it an implementation of IPreparePizzaExtension - after all, I've told it to!
So my question is, how on earth do I pass this to the service? I can manage this easily enough in a console app scenario, using the WorkflowInvoker, but I cannot see any obvious way to do this via the service approach. I would assume that obviously a programmatic approach to adding the reference is what's needed, but again I'm at a loss as to precisely how to go about this.
Any help would be greatly appreciated.
Best regards
Ian
The WorkflowServiceHost has a WorkflowExtensions property where you can add the workflow extenstion. There are several ways you can do that. If you are self hosting this is easy as you create the WorkflowServiceHost. If you are usign IIS you need to create a ServiceHostFactory to configure you WorkflowServiceHost. Finally there is an option to add the workflow extension in the CacheMetadata of your activity using the metadata.AddDefaultExtensionProvider() function.
Solved it as follows, self-hosting style:
static void Main(string[] args)
{
Workflow1 workflow = new Workflow1();
// Provide some default values; note: these will be overriden once method on the service is called.
workflow.productID = -1;
Uri address = new Uri("http://localhost:1234/WorkflowService1");
WorkflowServiceHost host = new WorkflowServiceHost(workflow, address);
// Behaviours
host.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = true });
host.Description.Behaviors.Remove(typeof(ServiceDebugBehavior));
host.Description.Behaviors.Add(new ServiceDebugBehavior { IncludeExceptionDetailInFaults = true });
// Persistence
var connStr = #"";
var behavior = new SqlWorkflowInstanceStoreBehavior(connStr);
behavior.InstanceCompletionAction = InstanceCompletionAction.DeleteNothing;
behavior.InstanceLockedExceptionAction = InstanceLockedExceptionAction.AggressiveRetry;
behavior.InstanceEncodingOption = InstanceEncodingOption.None;
host.Description.Behaviors.Add(behavior);
// Add extension implementations
if (!TEST_MODE)
{
host.WorkflowExtensions.Add(new MyExtension());
}
else
{
host.WorkflowExtensions.Add(new MyExtensionTest());
}
host.Faulted += new EventHandler(host_Faulted);
host.Open();
foreach (System.ServiceModel.Description.ServiceEndpoint endpoint in host.Description.Endpoints)
{
Console.WriteLine(endpoint.Address);
}
Console.WriteLine("Listening...");
Console.ReadLine();
host.Close();
}
My toolkit has configuration support for this. See http://neovolve.codeplex.com/wikipage?title=Neovolve.Toolkit.Workflow.dll%20-%201.1
There is also this method of doing things:
http://wf.codeplex.com/wikipage?title=How%20do%20I%20add%20an%20extension%20to%20a%20WCF%20Workflow%20Service?

Can we host a Workflow Service as a Windows Service?

I am working on a logging application that requires me to have a Workflow that is exposed as a Service (Workflow Service). We want to host it as a Windows Service (don't want to host workflow service as .svc file in IIS). Another reason for having it as windows service is to be able to communicate with the service through the Named pipes.
Can we expose a Workflow Service through Named Pipes without hosting it in IIS?
Yep bep, you sure can. At least, I have accomplished as much with Workflow 4 Release Candidate.
Consider,
// a generic self-hosted workflow service hosting thingy. Actual
// implementation should contain more logging and thread safety, this
// is an abbreviated version ;)
public class WorkflowHost
{
// NOTE: with Workflow, it helps to maintain a concept of
// Workflow definition [the Activity or WorkflowService from
// a designer] and a Workflow instance [what is running within
// WorkflowInvoker, WorkflowApplication, WorkflowServiceHost].
// a definition may be used to generate an instance. an instance
// contains run-time state and cannot be recycled into a new
// instance. therefore, to repeatedly re-host a WorkflowService
// we need to maintain references to original definitions and
// actual instances. ergo services and hosts maps
//
// if you are special purpose and require support for one and
// only one service and endpoint\uri, then you may reduce this
// to a simple tuple of Uri, WorkflowService, WorkflowServiceHost
// services represents a definition of hosted services
private readonly Dictionary<Uri, WorkflowService> _services =
new Dictionary<Uri, WorkflowService> ();
// hosts represents actual running instances of services
private readonly Dictionary<Uri, WorkflowServiceHost> _hosts =
new Dictionary<Uri, WorkflowServiceHost> ();
// constructor accepts a map of Uris (ie service endpoints) to
// workflow service definitions
public WorkflowHost (IDictionary<Uri, WorkflowService> services)
{
foreach (KeyValuePair<Uri, WorkflowService> servicePair in services)
{
_services.Add (servicePair.Key, servicePair.Value);
}
}
// have your windows service invoke this to start hosting
public void Start ()
{
if (_hosts.Count > 0)
{
Stop ();
}
foreach (KeyValuePair<Uri, WorkflowService> servicePair in _services)
{
WorkflowService service = servicePair.Value;
Uri uri = servicePair.Key;
WorkflowServiceHost host = new WorkflowServiceHost (service, uri);
host.Open ();
_hosts.Add (uri, host);
}
}
// have your windows service invoke this to stop hosting
public void Stop ()
{
if (_hosts.Count > 0)
{
foreach (KeyValuePair<Uri, WorkflowService> servicePair in
_services)
{
WorkflowService service = servicePair.Value;
Uri uri = servicePair.Key;
IDisposable host = _hosts[uri];
host.Dispose ();
}
_hosts.Clear ();
}
}
}
I believe endpoint configuration may be set via standard Wcf service configuration sections in App.config. I have not personally attempted a change to default transport layer in my experiments with Workflow.
The above represents a generic pure hosting class [ie it self-hosts WorkflowServices]. This allows us to re-use this hosting functionality within a console, WinForm, WPF, or yes, even a WindowsService application. Below is a WindowsService that leverages our host class
// windows service. personally i would abstract service behind
// an interface and inject it, but again, for brevity ;)
public partial class WorkflowWindowsService : ServiceBase
{
WorkflowHost _host;
public WorkflowWindowsService ()
{
InitializeComponent();
Dictionary<Uri, WorkflowService> services =
new Dictionary<Uri, WorkflowService> ();
// do your service loading ...
// create host
_host = new WorkflowHost (services);
}
protected override void OnStart(string[] args)
{
_host.Start ();
}
protected override void OnStop()
{
_host.Stop ();
}
}
If you have fiddled with WorkflowServices in VS2010RC, then you may already know that WorkflowServices are not first class Xaml classes like their Workflow cousins. Instead, they are saved as loose Xaml files with the .xamlx extension. There is no design-time intellisense support for WorkflowServices [as far as I know] and are not recognized as declared types, so our only options to load a WorkflowService at run-time are
Read pure Xaml markup from .xamlx file directly
Read pure Xaml markup from some other source [embedded string, resource, or other source]
Either way, we must interpret markup and create a WorkflowService definition. The following will transform a string [that may be a filename or markup] into a WorkflowService. Keeners may also note that there is a difference between this process and the process for transforming Workflow markup to Workflow definitions.
// converts a string value [either pure xaml or filename] to a
// WorkflowService definition
public WorkflowService ToWorkflowService (string value)
{
WorkflowService service = null;
// 1. assume value is Xaml
string xaml = value;
// 2. if value is file path,
if (File.Exists (value))
{
// 2a. read contents to xaml
xaml = File.ReadAllText (value);
}
// 3. build service
using (StringReader xamlReader = new StringReader (xaml))
{
object untypedService = null;
// NOTE: XamlServices, NOT ActivityXamlServices
untypedService = XamlServices.Load (xamlReader);
if (untypedService is WorkflowService)
{
service = (WorkflowService)(untypedService);
}
else
{
throw new ArgumentException (
string.Format (
"Unexpected error reading WorkflowService from " +
"value [{0}] and Xaml [{1}]. Xaml does not define a " +
"WorkflowService, but an instance of [{2}].",
value,
xaml,
untypedService.GetType ()));
}
}
return service;
}
Yes it is possible. You will have to create your own service. See Hosting and Consuming WCF Services on MSDN, especially the section Hosting in Windows Services.

How to implement IsOneWay=true in WCF nettcpBinding

How can I implement one way WCF operations?
I just tried using IsOneWay attribute as:
[OperationContract(IsOneWay=true)]
void MethodName(string param1, int param2)
Is there any other change I need to make or any specific change in app.config?
FYI, my WCF service implements netTcpBinding, though I think that shouldn't make any difference.
As shown, your code looks ok. There should be no problem with doing one-way calls with netTcpBinding.
If you're interested, chapter 5 in Juval Lowy's awesome Programming WCF Services 2nd Edition contains a good bit of information about one-way services.
From what you've shown, so far though I don't see anything wrong. Please give us some more details.
We had a problem with one-way calls not returning immediately using the NetTcpBinding. This blog post identifies the problem and provides a solution.
http://blogs.msdn.com/b/distributedservices/archive/2009/02/12/client-proxy-close-method-call-does-not-finish-immediately-in-one-way-wcf-calls.aspx
From the article:
Problem: Clients calling a one-way method in WCF Service and then close method on proxy does not return until the call is actually finished or call times out. Ever wonder why this happens?
Cause: When you specify “One-Way” on your interface, the underlying channel operation is still two-way since the one way binding element is not in the channel stack. Thus, the close operation gets blocked until the one way operation completes.
This is by design and the development team is working to change it in future versions of .Net framework.
...
Solution (Work around):
Layer the OneWayBindingElement on top of netTcpBinding as shown in the below code. This way, close call on proxy will return immediately and eventually the one-way call will return in fire and forget fashion.
[ServiceContract]
public interface IService1
{
[OperationContract(IsOneWay = true)]
void SetData(int value);
}
public class Service1 : IService1
{
public void SetData(int value)
{
//Application specific code
}
}
Service Host code:
Form1ServiceHost = new ServiceHost(this, new Uri("net.tcp://localhost:8091/WindowsFormApp/Form1/"), new Uri("http://localhost:8090/WindowsFormApp/Form1/"));
Binding binding = new NetTcpBinding();
BindingElementCollection oldBindingElements = binding.CreateBindingElements();
BindingElementCollection bindingElements = new BindingElementCollection();
bindingElements.Add(new OneWayBindingElement());
foreach (BindingElement bindingElement in oldBindingElements)
{
bindingElements.Add(bindingElement);
}
binding = new CustomBinding(bindingElements);
Form1ServiceHost.AddServiceEndpoint("WCFServiceLibrary.IService1", binding, "");
Form1ServiceHost.Open();
Client Code:
Binding binding = new NetTcpBinding();
BindingElementCollection oldBindingElements = binding.CreateBindingElements();
BindingElementCollection bindingElements = new BindingElementCollection();
bindingElements.Add(new OneWayBindingElement());
foreach (BindingElement bindingElement in oldBindingElements)
{
bindingElements.Add(bindingElement);
}
binding = new CustomBinding(bindingElements);
Service1Client client = new Service1Client(binding, new EndpointAddress("net.tcp://localhost:8091/WindowsFormApp/Form1/"));
client.SetData(10);
Console.WriteLine("set data");
Console.WriteLine("Now closing the channel,Before close, current time is {0}", DateTime.Now.ToString() + " " + DateTime.Now.Millisecond.ToString());
client.Close();
Console.WriteLine("Now closing the channel,After close, current time is {0}", DateTime.Now.ToString() + " " + DateTime.Now.Millisecond.ToString());`