0

I'm trying to create a Web API service but when I'm trying to run as service I get NullReferenceException. It's working well if I remove the ServiceBase part. If I replace the Thread to do nothing, then it's working as usual.

What could be causing the NullReferenceException?

namespace WebApi
{
    public class Program
    {
        public static void Main(string[] args)
        {
            //To Debug
             //BuildWebHost(args).Run();

             //To Run as Service 
             using (var service = new TestService())
             {
                ServiceBase.Run(service);
             }
        }

        public static IWebHostBuilder BuildWebHost(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .UseUrls("http://localhost:5000");

    }
}
class TestService : ServiceBase
    {
        public TestService()
        {
            ServiceName = "TestService";
        }

        protected override void OnStart(string[] args)
        {
            string filename = CheckFileExists();
            File.AppendAllText(filename, $"{DateTime.Now} started.{Environment.NewLine}");            
            Thread t = new Thread(new ThreadStart(Program.BuildWebHost(args).Build().Run));
            t.Start();
        }

        protected override void OnStop()
        {
            string filename = CheckFileExists();
            File.AppendAllText(filename, $"{DateTime.Now} stopped.{Environment.NewLine}");
        }

        private static string CheckFileExists()
        {
            string filename = @"c:\tmp\MyService.txt";
            if (!File.Exists(filename))
            {
                File.Create(filename);
            }

            return filename;
        }

    }
Nguyễn Văn Phong
  • 13,506
  • 17
  • 39
  • 56
Foong
  • 45
  • 6

1 Answers1

0

It is hard to find the NullReferene by code. But you can make it debuggable with the following approach:

var s1 = new TestService();
if (!Environment.UserInteractive)
    ServiceBase.Run(new ServiceBase[] { s1 }); // when running as service
else
{
    s1.Start(args); // when running as console
    Console.ReadLine();
    s1.Stop();
}

this will start as windows service or console application.

Put this code to the Program.Main method and run under debug.

PS there is Topshelf library also that can deal this stuff for you (run application as service or console).

PPS seems that you will need to add public void TestService.Start method to make this UserInteractive approach works:

public class TestService : ServiceBase
{
  // existing code

  public void Start(string[] args)
  {
    OnStart(args);
  }

  public void Stop()
  {
    OnStop();
  }
}
oleksa
  • 3,688
  • 1
  • 29
  • 54