拥有Topshelf的Nancy在作为服务运行时不起作用? C#

时间:2017-11-28 07:39:13

标签: c# .net multithreading nancy topshelf

我用Nancy创建了一些自托管,然后我希望应用程序作为服务运行。所以我用topshelf来构建它。然后,当我调试我的程序或运行.exe时,程序运行良好。但是当我安装.exe作为服务并启动服务时。我无法调用我用nancy创建的API(仅在浏览器中#34;等待localhost .."不返回错误或成功)。是因为工作目录,线程还是其他什么?谢谢

这是我的代码: Program.cs

public class Program
{
    [STAThread]
    public static void Main()
    {
        var thread = new Thread(WorkerMethod);
        thread.SetApartmentState(ApartmentState.STA);
        thread.IsBackground = false;
        thread.Start();
    }

    public static void WorkerMethod(object state)
    {
        HostFactory.Run(x =>
        {
            x.Service<HostingAPI>(s =>
            {
                s.ConstructUsing(name => new HostingAPI());
                s.WhenStarted(tc => tc.Start());
                s.WhenStopped(tc => tc.Stop());
            });

            x.RunAsLocalSystem();
            x.SetDescription("Hardware hosting API");
            x.SetDisplayName("Hosting Services for Hardware");
            x.SetServiceName("Hardware Services");
        });
    }
}

CDM_Module(南希模块)

public class CDM_Module : NancyModule
{
    public CDM_Module()
    {
        try
        {
            Get["/CDM/Machine/Start"] = parameters =>
            {
                var ins = HostingAPI.Instance;
                bool result = ins.InitCDM_Thread();

                return Response.AsJson(result);
            };

            Get["/CDM/Machine/OpenGate"] = parameters =>
            {
                var ins = HostingAPI.Instance;
                bool result = ins.StartProcess_Thread();

                return Response.AsJson(result);
            };

            Get["/CDM/Machine/CloseGate"] = parameters =>
            {
                var ins = HostingAPI.Instance;
                bool result = ins.StopProcess_Thread();

                return Response.AsJson(result);
            };
        }
        catch
        {
        }
    }
}

HostingAPI.cs(启动和停止功能以及一个为API调用的函数)

public class HostingAPI
{
    //global variable
    private NancyHost mainHost;
    public static HostingAPI Instance;
    private string hostUrl;
    //public static MainCDM Ins = new MainCDM();

    public clsCSDDPMControl ObjDPMControl = new clsCSDDPMControl();
    public ClsPrinterControl ObjPrinterControl = new ClsPrinterControl();

    //webservice
    HttpClient httpClient = new HttpClient();

    public void Start()
    {
        //set hosturl dari document xml nantinya
        //sementara default
        //under construction
        Config.ReadConfiguration();

        //set awal entity
        buildEntity();

        AddEventCDM();
        AddEventPrinter();

        Instance = this;

        if (hostUrl == null) hostUrl = "http://localhost:5030";

        mainHost = new NancyHost(new Uri(hostUrl));
        mainHost.Start();

        //Console.WriteLine("Hardware Hosting API is running on " + hostUrl);

    }

    public void Stop()
    {
        mainHost.Stop();
        //Console.WriteLine("Service stopped!");
    }

    public bool InitCDM_Thread()
    {
        var thread = new Thread(InitCDM);
        thread.SetApartmentState(ApartmentState.STA);
        thread.IsBackground = false;
        thread.Start();
        Dummy.m_autoreset.WaitOne();
        return rtn;
    }

    private void AddEventCDM()
    {
        ObjDPMControl.EvtBoxFullReceived += new clsCSDDPMControl.EvtBoxFullReceivedEventHandler(ObjDPMControl_EvtBoxFullReceived);
        ObjDPMControl.EvtDocDataReceived += new clsCSDDPMControl.EvtDocDataReceivedEventHandler(ObjDPMControl_EvtDocDataReceived);
        ObjDPMControl.EvtDocumentCounterReceived += new clsCSDDPMControl.EvtDocumentCounterReceivedEventHandler(ObjDPMControl_EvtDocumentCounterReceived);
        ObjDPMControl.EvtDPMShellMsgReceived += new clsCSDDPMControl.EvtDPMShellMsgReceivedEventHandler(ObjDPMControl_EvtDPMShellMsgReceived);
        ObjDPMControl.EvtErrMsgReceived += new clsCSDDPMControl.EvtErrMsgReceivedEventHandler(ObjDPMControl_EvtErrMsgReceived);
        ObjDPMControl.EvtEventsReceived += new clsCSDDPMControl.EvtEventsReceivedEventHandler(ObjDPMControl_EvtEventsReceived);
        ObjDPMControl.EvtImageStoredReceived += new clsCSDDPMControl.EvtImageStoredReceivedEventHandler(ObjDPMControl_EvtImageStoredReceived);
        ObjDPMControl.EvtImageStoredErrorReceived += new clsCSDDPMControl.EvtImageStoredErrorReceivedEventHandler(ObjDPMControl_EvtImageStoredErrorReceived);
        ObjDPMControl.EvtStatusReceived += new clsCSDDPMControl.EvtStatusReceivedEventHandler(ObjDPMControl_EvtStatusReceived);
        ObjDPMControl.AxEvtBackTraceFileReady += new clsCSDDPMControl.AxEvtBackTraceFileReadyEventHandler(ObjDPMControl_AxEvtBackTraceFileReady);
        ObjDPMControl.AxEvtComPortError += new clsCSDDPMControl.AxEvtComPortErrorEventHandler(ObjDPMControl_AxEvtComPortError);
        ObjDPMControl.AxEvtExtraImageError += new clsCSDDPMControl.AxEvtExtraImageErrorEventHandler(ObjDPMControl_AxEvtExtraImageError);
        ObjDPMControl.AxEvtFrontDitherReady += new clsCSDDPMControl.AxEvtFrontDitherReadyEventHandler(ObjDPMControl_AxEvtFrontDitherReady);
        ObjDPMControl.AxEvtOutOfOrder += new clsCSDDPMControl.AxEvtOutOfOrderEventHandler(ObjDPMControl_AxEvtOutOfOrder);
        ObjDPMControl.AxEvtRearDitherReady += new clsCSDDPMControl.AxEvtRearDitherReadyEventHandler(ObjDPMControl_AxEvtRearDitherReady);

        DeviceReplyCode = Convert.ToInt32(ObjDPMControl.InitDevices(Config.DpmIniFile));

    }

    private void InitCDM()
    {
        DeviceReplyCode = Convert.ToInt32(ObjDPMControl.InitDevices(Config.DpmIniFile));

        if (DeviceReplyCode == ObjDPMControl.CSDeviceSuccessCode)
        {
            if (ObjDPMControl.StartDPMEngine() == true)
            {
                if (ObjDPMControl.DPMSetTimeouts() == true)
                {
                    rtn = true;
                }
                else
                {
                    rtn = false;
                }
            }
            else
            {
                rtn = false;
            }
        }
        else
        {
            rtn = false;
        }

        Dummy.m_autoreset.Set();
    }
}

编辑

已经尝试捕捉异常,但没有人抓住。 我尝试评论Dummy.m_autoreset.WaitOne()和Dummy.m_autoreset.Set()。现在API工作但是InitCDM()内的函数没有执行?在该功能中,我将一些库称为机器,而不是机器直接或通过事件处理程序提供反馈。我认为我使用AddEventCDM()创建的eventhandler无法通过库访问,因为该线程不再可用?有什么建议吗?

1 个答案:

答案 0 :(得分:0)

尝试在Start()方法中的新线程上启动NancyHost。在我的情况下,Start()方法没有返回,因此无法作为Windows服务启动。