所以我在这个问题上被困了大约一个星期。我正在尝试运行一个项目来接收TCP连接并启动一个SignalR集线器即服务。两者都能很好地将项目作为.exe文件运行。TCP部分可以很好地工作,但是我在SignalR端遇到了问题。
原因最终是using语句。
之前的
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()
来保持控制台打开,就像您需要它来保持控制台打开一样。一旦使用包装器的与控制台一起被删除,它就可以在.exe和服务中工作。
我读到过,一旦您离开包装器,using语句就会杀死其中的对象。但是我不明白之后的代码是如何让.exe代码在运行后保持打开的。在中使用有什么意义吗?还是我用错了?
编辑
protected override void OnStart(string[] args)
{
Task.Factory
.StartNew(() => StartTCP())
.ContinueWith(t => StartSignalR());
}
该调用是从StartSignalR()
方法发出的。
发布于 2015-12-23 16:04:32
你的服务出了什么问题?
你遇到的问题是你的Console.ReadLine
对标准输入做了阻塞等待。这将在windows服务上永远阻塞,并导致服务控制管理器在30秒后使服务启动超时。This question有更多关于正在发生的事情的信息。
如果删除using语句的全部内容以及语句本身,则在服务Start
方法完成后,由WebApp.Start
启动的服务器将在后台继续运行。这是服务的正确行为。
您在这里所做的有效操作是泄漏WebApp.Start
创建的异步工作进程。这意味着它们在服务启动完成后仍在运行以侦听请求。
您可能应该跟踪WebApp.Start
返回的IDisposable
,并在Stop
方法中处理它。
那using
呢?
当控制离开using
语句的块时,using
statement确保资源总是被释放。这可能是因为抛出了异常,也可能是因为块成功完成并且控制转移到程序的下一部分。
当您知道在块完成后没有任何东西想要访问资源时,就会使用using
语句。在处理向您返回IDisposable
的方法时,通常会出现这种情况。但是,在您的示例中,您不希望调用dispose,因为您希望WebApp.Start
创建的线程在服务启动后继续运行。
发布于 2015-12-23 16:05:03
Webapp.Start<>启动工作线程。这些线程使您的exe保持运行,即使在HelloWorld.cs中的代码完成执行之后也是如此。在停止所有工作线程之前,您的exe不会关闭。
当您添加“使用”-statement时,框架将在SignalR应用程序上调用Dispose。此调用将停止所有工作线程,并且您的exe将终止。
Readline()语句阻止应用程序到达using语句的末尾。这意味着在按enter键之前不会调用dispose方法。
因此,对于exe,您通常希望使用ReadLine的方式。对于要存储对IDisposable的引用的服务,请在Stop()方法中对其调用dispose。
https://stackoverflow.com/questions/34431051
复制相似问题