首页 文章

Nancyfx自托管无法阻止HttpListener

提问于
浏览
4

我有一个应用程序,它具有基于NancyFx的休息服务,我发现它非常酷的框架 . 但是我有一个很大的问题就是阻止它 . 我的主机类看起来像这样:

public class RestHost : IStartStopAble
{
    private readonly string _uri;
    private readonly IWindsorContainer _container;
    private NancyHost _host;
    private Thread _wsThread;
    private WindsorBootstrapper _windsorBootstrapper;

    public RestHost(string uri, IWindsorContainer container)
    {
        _uri = uri;
        _container = container;
    }

    public void Start()
    {
        var uri = new Uri(_uri);

        _windsorBootstrapper = new WindsorBootstrapper(_container);
        _host = new NancyHost(uri, _windsorBootstrapper);

        _host.Start();
    }

    public void Stop()
    {
        _host.Dispose();
    }
}

如你所见,我和南茜一起使用windsor . 一切都很好,我从主线程调用开始,停止和构造函数,但当我处置我的主机时,我 grab 这个:

HttpListener: HttpListenerException: The I/O operation has been aborted because of either a thread exit or an application request

例外 . 我找到了这篇论文:http://maykov.blogspot.ru/2009/02/c-httplistener-httplistenerexception-io.html但是我使用主线程并且不明白我怎么能创建HttpListener的线程,以及如何将它传递给Nancy .

我将非常感谢任何帮助,我甚至不知道,我在.Net框架的核心中如何处理HttpListener异常 .

2 回答

  • 5

    你可能还记得 SynchronizationContext

    public void Start()
    {
        // init _host ...
    
        _syncContext = SynchronizationContext.Current;
        _host.Start();
    }
    
    public void Stop()
    {
        if (_syncContext == SynchronizationContext.Current)
        {
            _host.Dispose();
        }
        else
        {
            _syncContext.Post((state) =>
            {
                _host.Dispose();
            }
            , null);
        }
    }
    
  • 1

    它对我不起作用,因为当前正在运行 Quartz Scheduler . NancyBootstrapper没有关闭进程的虚方法 . 所以这是我的解决方案:

    在NancyBootStrapper.ApplicationStartup我'm setting scheduler to static class (which is i'我对这个名为 GlobalModule.TaskScheduler 的字段不满意:

    GlobalModule.TaskScheduler = ScheduleTasksAndStartScheduler(container);
    GlobalModule.Logger = _logger;
    

    这是GlobalModule:

    public static class GlobalModule
    {
        public static ILogger Logger;
        public static ITaskScheduler TaskScheduler;
    
        public static void StopScheduler()
        {
            if (TaskScheduler == null) return;
            try
            {
                TaskScheduler.Stop();
            }
            catch (Exception ex)
            {
                if (Logger != null)
                {
                    Logger.Error("TaskScheduler.Stop()", ex);
                }
            }
        }
    }
    

    最后是Program.Stop:

    private static void Stop(NancyHost host)
        {
            GlobalModule.StopScheduler();
            if (_syncContext == SynchronizationContext.Current)
            {
                host.Dispose();
            }
            else
            {
                _syncContext.Post((state) =>
                {
                    host.Dispose();
                }
                , null);
            }
            try
            {
                host.Stop();
            }
            catch (Exception ex)
            {
                Console.WriteLine(string.Format("Exception: {0}\r\n Stack Trace: {1}", ex.Message, ex.StackTrace));
            }
        }
    

    亲切的问候...

相关问题