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