所以我被困在这个问题大约一个星期.我试图运行一个项目来接收TCP连接并启动SignalR Hub作为服务.两者都完美地将项目作为.exe文件运行.TCP部分可以完美地工作,但是我遇到了SignalR方面的问题.
原因最终是使用声明.
之前
using (WebApp.Start(url)) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Server running on {0}", url); // was url Console.WriteLine("ID\tMessage"); Console.ReadLine(); }
后
WebApp.Start(url);
我曾尝试使用Console.WriteLine()
注释掉的代码来运行代码,因为我认为它可能会抛出一个异常,因为没有控制台输出到一次作为服务运行.这也不起作用,但也不能作为.exe文件工作,因为它需要Console.ReadLine()
保持控制台打开,排序你需要它来保持HelloWorld.cs打开.一旦使用的包装器与控制台一起被移除,它将在.exe和服务中工作.
我已经读过,一旦你离开包装器,using语句会杀死它中的对象.但我不明白After bit代码如何在运行时保持.exe代码打开.有没有使用任何点使用或曾经我一直在使用它错了吗?
编辑
protected override void OnStart(string[] args) { Task.Factory .StartNew(() => StartTCP()) .ContinueWith(t => StartSignalR()); }
该调用是从该StartSignalR()
方法进行的.
你遇到的问题是你Console.ReadLine
做了阻塞等待标准输入.这将永久阻止Windows服务并导致服务控制管理器在30秒后超时服务启动.这个问题提供了有关正在发生的事情的更多信息.
如果删除using语句的全部内容,并且语句本身已完成,那么启动的服务器WebApp.Start
将在服务Start
方法完成后在后台继续.这是服务的正确行为.
你在这里有效地做的是泄漏WebApp.Start
创建的异步工作者.这意味着它们在服务启动完成后仍在运行以侦听请求.
你或许应该跟踪的IDisposable
是WebApp.Start
返回虽然,在处理它Stop
的方法.
using
?一using
言可以确保当控制离开一个资源始终置于using
语句的块.这可以是由于被抛出的异常或因为块成功和控制移动完成到的节目的下一个部分.
using
如果您知道在块完成后没有任何东西想要访问资源,则使用语句.当您处理返回IDisposable
给您的方法时,通常就是这种情况.但是,在您的情况下,您不希望调用dispose,因为您希望WebApp.Start
在服务启动后创建的线程继续.
Webapp.Start <>启动工作线程.即使在HelloWorld.cs中的代码完成执行后,这些线程也会使您的exe运行.在所有工作线程都停止之前,您的exe不会关闭.
当您添加"using"-statement时,框架将在您的SignalR应用程序上调用Dispose.此调用将停止所有工作线程,您的exe将终止.
Readline()语句阻止应用程序到达using语句的末尾.这意味着只有按Enter键才会调用dispose方法.
因此,对于exe,您通常希望以您的方式使用ReadLine.对于服务要存储到您的IDisposable参考,并调用Dispose它在你stop()方法.