解释为什么“;使用“;赢得';我不在服役

本文关键字:为什么 使用 赢得 解释 | 更新日期: 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。