1

I have a Windows Service project in whose OnStart method, I am calling a function from a reference WCF Service like this -

var factory = new ChannelFactory<MySolution.IDataService>("BasicHttpBinding_IDataService");
        MySolution.IDataService client = factory.CreateChannel();

Task.Factory.StartNew(() => client.GetData()).Wait();

After hosting this, when I try to start the service, it is throwing error that it "was started and then stopped". I debugged and found that the last line (with Wait call) is causing the service to break. What can be the reason of this? How to fix it?

Thanks in advance.

Edit1

As suggested, I moved the GetData code to another function which is called with a timer -

   OnStart(){
         ....
         ....

         System.Timers.Timer _timer = new Timer(60 * 1000);
        _timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
        _timer.Start();
    }

    private void timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        Task.Factory.StartNew(() => client.GetData()).Wait();
    }

Now service is starting but the timer_Elapsed function is not invoked, or may be it is but the function is again failing. The function works fine in debug mode. Can you tell if this is the correct way?

Sam
  • 4,302
  • 12
  • 40
  • 74
  • Why would you use a timer when it looks like you want to start immediately? Why are you waiting on a task that was just started? Can'you just do `Task.Factory.StartNew(() => client.GetData())` right in OnStart? – usr May 05 '15 at 21:40
  • @usr Actually I do need to run it every minute after the first time. As Chris suggested to not do this in OnStart, I moved it entirely to timer_Elapsed function. Now even though service is getting started but GetData is not at all getting called from timer_Elapsed. Not sure why. – Sam May 05 '15 at 21:55
  • It works when I am debugging it. – Sam May 05 '15 at 22:02
  • @usr Ok, I did what you suggested as well. But it didn't work for me. – Sam May 05 '15 at 22:13
  • After your edit it may not work when you are not debugging because you do not hold the reference to _timer - so it will be garbage collected. There are [other implications when using System.Timers.Timer](http://stackoverflow.com/questions/9208378/why-doesnt-windows-service-work-properly-with-system-timers-timer-or-system-win), so you may want to [read up on different .net timers](https://msdn.microsoft.com/en-us/magazine/cc164015.aspx) – anikiforov May 06 '15 at 07:44
  • Actually the call is not happening in both cases - with or without timer. Are there any issues related to calling another wcf function from windows service this way? Because, when I debug, the call happens. I will look at the timer part too. – Sam May 06 '15 at 07:47
  • Add error handling. There is an exception that is swallowed by the task. – usr May 06 '15 at 08:07
  • Ok, so now I added a try-catch block, and writing exception to a file. Also, writing a message to the file when inside the GetData function. Now when I run service, there is no message written to the file (nor from exception block and nor from GetData function). When I am debugging GetData function is writing properly to the file. Not sure whats going on here. – Sam May 06 '15 at 08:25
  • Maybe you have no rights to write to the file from the service. That will crash which is also swallowed. Debug the service. Set the debugger to halt on all exception. – usr May 06 '15 at 09:03
  • Yes, have done that. But how to debug the attach it to windows service? – Sam May 06 '15 at 09:09
  • By entering "debug .net service" into a search engine. – usr May 06 '15 at 09:13
  • This is the error - There was no endpoint listening at "service url" that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details. Unable to connect to the remote server – Sam May 06 '15 at 09:48

2 Answers2

0

When starting a Windows service you need to make sure that the OnStart method returns in a "timely" manner. This means that it can't start a long running task in the actual method itself.

In your case, what you will need to do is put the code into a thread and start the thread up from the OnStart method.

ChrisF
  • 134,786
  • 31
  • 255
  • 325
0

As per the comments debugging the service turned out that the WCF call failed. The error was swallowed which is the default behavior for unobserved Task exceptions in recent .NET versions.

  1. Add error handling so that you find out about errors.
  2. Correctly unblock the OnStart method. For example:

.

Task.Run(() => {
 try {
  client.GetData();
 }
 catch (Exception ex) { Log(ex); }
});
  1. Debug the failed WCF call independently of the service and task issues. They have nothing to do with the problem. This is a standard WCF error that should be tackled using the usual techniques documented on the web.
usr
  • 168,620
  • 35
  • 240
  • 369