解释为什么“;使用“;赢得';我不在服役
本文关键字:为什么 使用 赢得 解释 | 更新日期: 2023-09-27 18:27:47
所以我被这个问题困扰了大约一个星期。我试图运行一个项目来接收TCP连接并启动SignalR集线器即服务。两者都完美地将项目作为.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()
来保持控制台的打开,就像你需要它来保持HelloWorld.cs的打开一样。一旦使用的包装器与控制台一起被移除,它将在.exe和服务中工作。
我读过using语句在您离开包装器后会杀死其中的对象。但我不明白代码的After部分是如何使.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
创建的异步工作者。这意味着在服务启动完成后,它们仍在运行以侦听请求。
您可能应该跟踪WebApp.Start
返回的IDisposable
,并在Stop
方法中处理它。
using
怎么样
using
语句确保在控件离开using
语句的块时总是释放资源。这可能是由于抛出异常,也可能是因为块成功完成,控制权转移到程序的下一部分。
当您知道在块完成后没有人想访问资源时,就会使用using
语句。当您处理返回IDisposable
的方法时,通常会出现这种情况。然而,在您的情况下,您不希望调用dispose,因为您希望WebApp.Start
创建的线程在服务启动后继续。
Webapp.Start<>启动工作线程。即使在HelloWorld.cs中的代码执行完毕之后,这些线程也会保持exe的运行。在停止所有工作线程之前,您的exe不会关闭。
当您添加"using"-语句时,框架将在SignalR应用程序上调用Dispose。此调用将停止所有工作线程,并且您的exe将终止。
Readline()语句阻止应用程序到达using语句的末尾。这意味着在按enter键之前不会调用dispose方法。
因此,对于exe,您通常希望使用ReadLine的方式。对于一个服务,您希望存储对IDisposable的引用,并在Stop()方法中对其调用dispose。