Starting a WCF service in Windows Service when initialization takes a long time - windows

I have a WCF project that I host in a windows Service (actually I use topshelf) and it runs fine. I have to make changes however that will cause the initialization to take substantially longer. This causes problems when the service starts as it times out while executing the WCF Service constructor.
I wanted to reduce the amount of code in the constructor and then when the service was opened I would do my longer running initializations. I put register the open event in the WCF ctor but it does not seem to be called.
public WCFService()
{
this.Faulted += WCF_Faulted;
this.Opened += WCF_Opened;
...
and event handlers
void WCF_Opened(object sender, EventArgs e)
{
}
void WCF_Faulted(object sender, EventArgs e)
{
}
I am guessing that I am not implementing this correctly.
I was able to trap the opened event in the servicehost but then I dont know how to access the instance (it is a singleton) to call a method on it.
Ideas?

Related

How can I create a WCF Service Application in Visual Studio that does NOT use a Web Server

I have a simple task: A program (executable) is supposed to call a function of another program (also executable) with some parameters. Program A is supposed to be started, call the function and then terminate. Program B is legacy program that has a GUI and runs continuously. Both programs run on the same Windows PC and use the .NET Framework. I have no experience in web development and Program B is not supposed to run as a web service! Named pipes seem like a good option.
I researched what the best method would be and wanted to try WCF. The documentation claims that "A service endpoint can be part of a continuously available service hosted by IIS, or it can be a service hosted in an application". From that I understand that I can run Program B as a service without hosting a web server.
However everything I see in Visual Studio seems to presume I want to run a server. Wenn I want to create a new WCF project in Visual Studio the only options are a library or "A project for creating WCF service application that is hosted in IIS/WAS". Once I've created said project the debugger wants me to choose a browser for hosting the service.
In another StackOverflow topic a popular suggestion was using this website as a guide and simply removing the http references since the guide is for both named pipes and http. Another indication that it should be possible.
So can someone point me in the right direction? What am I missing? How can I use WCF with nothing related to Web Development involved?
You have already been on the way, it is enough to host the web service in Program B, without specifying a web server. this is called a self-hosted WCF. As the link you provided mentioned, the Service host class is used to host the WCF service, which means that we can host the service in the Console/Winform, and so on.
Here is an example of hosting the service in a Winform application.
public partial class Form1 : Form
{
ServiceHost serviceHost = null;
public Form1()
{
InitializeComponent();
Uri uri = new Uri("http://localhost:9009");
BasicHttpBinding binding = new BasicHttpBinding();
serviceHost = new ServiceHost(typeof(MyService), uri);
serviceHost.AddServiceEndpoint(typeof(IService), binding, "");
ServiceMetadataBehavior smb = new ServiceMetadataBehavior()
{
HttpGetEnabled = true
};
serviceHost.Description.Behaviors.Add(smb);
System.ServiceModel.Channels.Binding mexbinding = MetadataExchangeBindings.CreateMexHttpBinding();
serviceHost.AddServiceEndpoint(typeof(IMetadataExchange), mexbinding, "mex");
serviceHost.Open();
}
private void Form1_Load(object sender, EventArgs e)
{
if (serviceHost.State==CommunicationState.Opened)
{
this.label1.Text = "Service is running";
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (serviceHost.State==CommunicationState.Opened&&serviceHost.State!=CommunicationState.Closed)
{
serviceHost.Close();
}
}
}
[ServiceContract]
public interface IService
{
[OperationContract]
string Test();
}
public class MyService:IService
{
public string Test()
{
return DateTime.Now.ToLongTimeString();
}
}
After that, we could consume it by using a client proxy.
https://learn.microsoft.com/en-us/dotnet/framework/wcf/accessing-services-using-a-wcf-client
Feel free to let me know if there is anything I can help with.

Background worker blocking UI when using web service call

For some reason when i put a long running web service call (doesn't matter if its a legacy one or WCF) in a background thread it seems to be locking up the UI main thread.
I cant see anything wrong with the code im putting in.
workerThreadInitialNotify = new BackgroundWorker();
workerThreadInitialNotify.WorkerSupportsCancellation = true;
workerThreadInitialNotify.DoWork += new DoWorkEventHandler(workerThreadInitialNotify_DoWork);
workerThreadInitialNotify.RunWorkerCompleted += new RunWorkerCompletedEventHandler(workerThreadInitialNotify_RunWorkerCompleted);
workerThreadInitialNotify.RunWorkerAsync();
Then in my do work i have a webservice call like:
void workerThreadInitialNotify_DoWork(object sender, DoWorkEventArgs e)
{
if (!(sender as BackgroundWorker).CancellationPending)
{
try
{
TestWebService service = new TestWebService();
service.RunLongRunningMethod();
}
catch(Exception ex)
{
}
}
}
When this thread is called, it occasionally locks up the UI thread, now i have setup the RunLongRunningMethod to purposely run slow and timeout (for testing purposes), but technically this shouldn't lockup the UI thread at all as its in a seperate thread.
Here is what the method contains:
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["customConnection"].ConnectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand("TestDelay", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
try
{
cmd.ExecuteNonQuery();
}
catch (Exception ee)
{
}
}
}
and TestDelay stored proc just contains this to simulate a delay so that the web service times out:
ALTER PROCEDURE [dbo].[TestDelay]
AS
WAITFOR DELAY '00:05:20';
The strange thing is that if i replace the web service call with a Thread.Sleep(20000); in the dowork, it runs perfectly, or even if i put a long running while loop it runs perfectly also.
I have no idea why specifically the webservice makes it lock up the UI.
ps: if i set up the webservice to be hosted locally to the Win Forms app, it runs ok, only when the webservice is running on another service, the strange lockup occurs.
ps (2): i am using devexpress library for ui controls of forms while the background thread runs in the background, not sure if this is related. I cant imagine why, if this is run in a seperate thread correctly
This ended up being a maxconnection .net setting in the App.config (its defaulted to a very low 2 by microsoft)
<system.net>
<connectionManagement>
<add address="*" maxconnection="40"/>
</connectionManagement>
</system.net>
Its now set to 40 and the issue has gone away.
There was multiple threads running at the same time, each calling web services, each of them were blocking each other.
There is more information in these links:
http://blogs.msdn.com/b/adarshk/archive/2005/01/02/345411.aspx
What is limiting the # of simultaneous connections my ASP.NET application can make to a web service?
http://msdn.microsoft.com/en-us/library/fb6y0fyc.aspx

How to make a synchronous web call from within a background agent

I am fairly new to wp7 development, and currently developing an app that has a background agent to update values based upon responses it gets from a web call to an api.
My problem is that the response to the web call is an asynchronous call and I can not access the results returned from within the background agent.
Is there any way that i can make a synchronous call from within the background agent so as to allow me to deal with the results within the same agent?
I have tried dealing with the web call within a class in a shared library but the Asynchronous call is only made after the onInvoke method of the agent has finished and so no use. Any Ideas would be great.
You simply need to call the NotifyComplete() method in your async call's Completed handler, and not before. Remove the call at the end of Invoke.
you could use an AutoResetEvent like this:
protected override void OnInvoke(ScheduledTask task)
{
AutoResetEvent are = new AutoResetEvent(false);
//your asynchronous call, for example:
WebClient wc = new WebClient();
wc.OpenReadCompleted += new OpenReadCompletedEventHandler(wc_OpenReadCompleted);
wc.OpenReadAsync(searchUri, channel);
// lock the thread until web call is completed
are.WaitOne();
//finally call the NotifyComplete method to end the background agent
NotifyComplete();
}
and your callback method should look like:
void wc_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
//do stuff with the web call response
//signals locked thread that can now proceed
are.Set();
}
remember that you should check if a connection is available and handle possible exceptions, if your background agent gets killed twice consecutively (due to memory consumed or duration) it will be disabled by the OS.

Timer and saving its state

I am building a windows phone application (basically its a game but I am not using XNA, Silverlight was enough). The graphics are moving based on a DispatcherTimer. What I want to do is basically stop the timer whenever a call arrives on the phone, and start it again after the call has finished, so that the game state is not lost.
I tried with :
// Code to execute when the application is activated (brought to foreground)
// This code will not execute when the application is first launched
private void Application_Activated(object sender, ActivatedEventArgs e)
{
Game.timer.Start();
}
// Code to execute when the application is deactivated (sent to background)
// This code will not execute when the application is closing
private void Application_Deactivated(object sender, DeactivatedEventArgs e)
{
Game.timer.Stop();
}
but it did not work, it actually does not reach to this point when a call arrives at the phone. Anyone had such experience?
Thanks in advance :)
When a call is received you will receieve the Obscured Event on the Frame.
Please note that this event can also be fired for more than just a received phone call though.

Ready event in Microsoft Outlook 2010?

Is there an event in Microsoft Outlook 2010 which one can subscribe on, in order to known when Outlook has finished initializing and all components, folders etc. have been loaded?
Not sure about VSTO but good ol' COM addins get the StartupComplete "event" (via IDTExtensibility2) for exactly that purpose.
Ok, I found out what I needed to do...
...
private void ThisAddInStartup(object sender, EventArgs e)
{
this.Application.Startup += ApplicationStartup;
this.Application.ItemLoad += ApplicationItemLoad;
}
void ApplicationItemLoad(object Item)
{
//Do something
}
private void ApplicationStartup()
{
//Do something
}
...
http://msdn.microsoft.com/en-us/library/ff869298.aspx
Not that I'm aware of. Usually, addins don't do anything that requires talking with many outlook objects till some triggering event happens (like opening a mail, or creating a new inspector) so THAT'S when you'd typically see some custom code hooked in.
In my addins, the code connected to startup does things like load up some config, and maybe connect to a DB (although even that I tend to do on demand vs once at startup).

Resources