重新启动由C#控制台应用程序托管的WCF服务

时间:2011-03-05 00:33:06

标签: c# wcf

我有一个托管在c#控制台应用程序上的WCF服务。有没有办法重新启动此服务,最好是通过调用服务本身的端点(例如myService.Restart())。

由于

5 个答案:

答案 0 :(得分:1)

当我执行远程WCF服务的自动更新时,我必须做类似的事情。在Restart()方法中,关闭主机:

    try
    {
        host.Description.Endpoints.Where(x => !x.Address.ToString().EndsWith("MEX")).ForEach(endpoint => _log.InfoFormat("Closing {0}", endpoint.Address));
        host.Close(TimeSpan.FromSeconds(5));
    }
    catch (Exception)
    {
        host.Abort();
    }

我等待我的更新申请,然后在成功或失败后,我使用与我之前用来启动它的相同代码重新打开主机。

如果您只是想立即重启,可以直接调用host.Open(),也可以设置一个计时器来调用它等。

try
{
    host.Open();
    host.Description.Endpoints.Where(x => !x.Address.ToString().EndsWith("MEX")).ForEach(endpoint => _log.InfoFormat("Host opened at: {0}", endpoint.Address));
}
catch (Exception ex)
{
    _log.Error("Unable to open host.", ex);
}

答案 1 :(得分:1)

要回答我的问题,我已通过以下方式解决了问题:

  • 将加载DLL文件的代码与WCF服务代码分离到另一个类库项目
  • 使用与在新项目中加载DLL文件的方法相同的方法签名创建一个接口(此接口现在由两个项目使用)
  • 在Web服务中,将其他项目加载到新的应用程序域中。这样,DLL文件被新的应用程序域锁定,而不是默认的。

如果我现在要更新我的nunit DLL文件,我所要做的就是从Web服务卸载应用程序域,更新文件,最后创建一个新的应用程序域。

AppDomain remoteDomain = AppDomain.CreateDomain("New Domain");
IClass1 class1 = (IClass1)remoteDomain.CreateInstanceFromAndUnwrap(
                           "Test1.dll", "Test1.Class1");

注意:IClass1是项目之间的通用接口。

答案 2 :(得分:0)

你绝对无法通过调用同一服务本身来“重启”故障服务。理论上,您可以在同一个过程中托管2个服务。将您想要的'restartable'放在公共静态变量中,然后在其他服务中重新启动它。问题是重新启动重新启动服务,如果它出现故障... :)并且您肯定希望重新启动服务受到“管理员式”限制,以便未经授权的用户无法执行此操作。

答案 3 :(得分:0)

这有点笨拙,但我想你可以在你的服务上公开一个主机可以附加的回调,并在触发时采取适当的行动。这将使您的主机能够决定“重启”的真正含义以及需要如何执行。更重要的是,它可以让你决定它是否应该做一些极端的事情,比如从观察者进程中产生然后离开自己或优雅地丢弃并重新安排你的服务(最好)。

Mmmmmm ...... kludge ....

答案 4 :(得分:0)

您无法要求服务重新启动。考虑一个具有RESTART功能的Windows服务(托管在windows提供的容器中的服务)。此处RESTART功能不是由服务提供,而是由容器提供。容器控制如何停止服务并启动它。

同样在您的情况下,如果您的容器可以提供您需要的功能,您应该尝试寻找选项。由于您希望远程控制它,因此容器也应该是远程可用的,如果容器是控制台应用程序,则无法实现。相反,它必须是另一个Web服务或Web应用程序。