【问题标题】:C# Windows Service "Pauses" System when starting during boot启动期间启动时 C# Windows 服务“暂停”系统
【发布时间】:2017-03-16 15:19:20
【问题描述】:

我编写了一个 Windows 服务,它使用 WCF Web 服务来监视各种系统活动。 它的启动类型设置为自动,并在系统启动时按预期启动。在 Windows 7 VirtualBox VM 中进行一些测试时,我注意到对 WCF 服务的初始调用超时。

在做了一些研究后,我发现在我的任何 c# 服务中,如果在启动后不让系统“稳定下来”一段时间,就向 Internet 发出任何类型的呼叫,导致系统基本上挂起大约一分钟和一个一半。我在其他裸机上试过这个,时间有点短,但它仍然会发生。 (可能是我以前没有注意到的原因。) 所以症状似乎是这样的。如果我将服务启动设置为自动(延迟启动),则只会访问 IP 网站的测试服务会立即执行,不会有任何延迟。如果我使服务自动启动并首先休眠大约 20 秒,它也会立即执行,没有延迟。如果我尝试在启动时立即执行命令,则服务会在 1:15 到 1:45 之间停留。

初步结论是,当我尝试访问网络时,有一个进程正在启动,但我无法确定是什么原因造成的。 我可以将服务设置为延迟启动并完成它,但这会冒犯我正确做事的感觉。

如果它是一个正在启动的服务,我想让我的服务依赖它......等等。 有任何想法吗?

我试图做到彻底,但这是我的第一个问题。我很乐意提供任何其他详细信息。谢谢。

这里是测试服务 OnStart 事件:

    protected override void OnStart(string[] args)
    {
        Logging.WriteLog("Starting");

        ServiceController sc = new ServiceController("Tcpip");
        Logging.WriteLog("TCPIP Status: " +sc.Status.ToString());

        sc = new ServiceController("DHCP");
        Logging.WriteLog("DHCP Status: " + sc.Status.ToString());

        sc = new ServiceController("Dnscache");
        Logging.WriteLog("DNS Status: " + sc.Status.ToString());

        Logging.WriteLog("Internal IP: " + getInternalIp());

        Logging.WriteLog("External IP: " + getExternalIp());
        Logging.WriteLog("Stopping");
    }

下面是 getExternalIP 方法的代码:

       private string getExternalIp()
    {
        try
        {
            string externalIP = "";
            try
            {
                //code hangs here
                externalIP = (new WebClient()).DownloadString("http://ipv4.icanhazip.com");
                externalIP = (new Regex(@"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"))
                             .Matches(externalIP)[0].ToString();
            }
            catch (Exception ex)
            {
                Logging.WriteLog(ex);
            }
            return externalIP;
        }
        catch (Exception ex)
        {
            Logging.WriteLog(ex);
            return null;
        }
    }

这是立即开始的输出:

2017 年 3 月 16 日上午 7:57:08:开始

2017 年 3 月 16 日上午 7:57:09:TCPIP 状态:正在运行

2017 年 3 月 16 日上午 7:57:09:DHCP 状态:正在运行

2017 年 3 月 16 日上午 7:57:09:DNS 状态:正在运行

2017 年 3 月 16 日上午 7:57:11:内部 IP:192.168.2.103

2017 年 3 月 16 日上午 7:58:30: 外部 IP:xxx.xxx.xxx.xxx

2017 年 3 月 16 日上午 7:58:30:停止

这是延迟启动输出:

2017 年 3 月 16 日上午 8:03:39:开始

2017 年 3 月 16 日上午 8:03:39:TCPIP 状态:正在运行

2017 年 3 月 16 日上午 8:03:39:DHCP 状态:正在运行

2017 年 3 月 16 日上午 8:03:39:DNS 状态:正在运行

2017 年 3 月 16 日上午 8:03:40:内部 IP:192.168.2.103

2017 年 3 月 16 日上午 8:03:40: 外部 IP:xxx.xxx.xxx.xxx

2017 年 3 月 16 日上午 8:03:40:停止

【问题讨论】:

  • 我经常对内部服务使用自动(延迟启动),以允许首先启动低级别服务。或者,您可以进行研究以确定您的服务需要哪些服务,并将它们配置为您的服务的依赖项。 serverfault.com/questions/24821/…

标签: c# windows wcf service network-programming


【解决方案1】:

在您的应用中使用异步,这样主线程就不会停止。但是,这会破坏您首先显示“停止”然后显示 IP 的一致性,因为对外部网站的调用可能需要一些时间才能解决。我建议调用 ExternalIP

  WebClient client = new WebClient();
  client.DownloadDataCompleted += DownloadDataCompleted;
  client.DownloadDataAsync(new Uri("http://ipv4.icanhazip.com"));


static void DownloadDataCompleted(object sender,
    DownloadDataCompletedEventArgs e)
{
    byte[] raw = e.Result;
    string data = System.Text.Encoding.Default.GetString(raw);
    data = (new Regex(@"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"))
                             .Matches(data)[0].ToString();
    Logging.WriteLog("External IP: " + data);                            
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-14
    相关资源
    最近更新 更多