3

簡単なWindowsサービスを作成しましたが、起動しようとすると、次のメッセージが表示されてすぐにシャットダウンします。

ローカルコンピューターのConsumerServiceサービスが開始され、その後停止されました。一部のサービスは、他のサービスまたはプログラムで使用されていない場合、自動的に停止します。

以下は私が実行しようとしているサービスです:

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    static void Main()
    {
        var servicesToRun = new ServiceBase[] 
                                          { 
                                              new ConsumerService() 
                                          };
        ServiceBase.Run(servicesToRun);
    }
}

public partial class ConsumerService : ServiceBase
{
    private readonly MessageConsumer<ClickMessage> _messageconsumer;
    private readonly SqlRepository _sqlrep;
    private static Timer _timer;
    public ConsumerService()
    {
        InitializeComponent();

    }

    protected override void OnStart(string[] args)
    {
        try
        {
            File.Create(@"c:\ErrorLog.txt");
            WriteToFile("Has started : " + DateTime.UtcNow);
            var t = new Timer(OnTimeEvent, null, 1000, 1000);
        }
        catch (Exception e)
        {
            WriteToFile("Error : " + e.Message);
        }
    }

    private void OnTimeEvent(object state)
    {
        WriteToFile("The time is : " + DateTime.UtcNow);
    }

    protected override void OnStop()
    {
        WriteToFile("Has stopped : " + DateTime.UtcNow);
    }

    private static void WriteToFile(string s)
    {
        var stream = File.AppendText(@"c:\ErrorLog.txt");
        stream.WriteLine(s);
    }
}

ご覧のとおり、1秒ごとにファイルに行を書き込むのは単純なタイマーにすぎないため、これによってサービスの実行が妨げられる理由に戸惑います。また、Windowsからのメッセージがこのサービスにどのように関連しているかを確認するのも困難です。これは、何かがすでに依存している場合を除いて、サービスの実行を妨げるためです。

4

3 に答える 3

2

これは、メイン スレッドでの未処理のエラーが原因である可能性が最も高いです。これを確認するにはイベント ログを確認しますが、コードをざっと見ると、関数WriteToFileがクラッシュしてサービス全体がダウンする可能性があります。

実際には、ストリームを開いたままにして (ファイルがロックされているため) クラッシュするはずであり、2 回目に開こうとするとエラーが発生します。

コードを次のように変更すると、このようなクラッシュが防止され、ファイルがロックされたままになるというバグが修正されます。

private static void WriteToFile(string s)
{
    try
    {
        using (var stream = File.AppendText(@"c:\ErrorLog.txt"))
        {
            stream.WriteLine(s);
            stream.Close();
        }
    }
    catch (Exception e)
    {
        Console.WriteLine("error writing to file: " + e);
        //...or any other means of external debug...
    }
}
于 2012-11-19T14:21:06.330 に答える
1

私が見ることができるように、あなたのコードは終了しています...したがって、プログラムの実行は自然に終了します。そのため、実行が終了したため、サービスも停止します。

于 2012-11-19T14:23:07.280 に答える
0

msdnから:

タイマーを使用している限り、タイマーへの参照を保持する必要があります。他のマネージド オブジェクトと同様に、Timer への参照がない場合、Timer はガベージ コレクションの対象になります。タイマーがまだアクティブであるという事実は、収集を妨げるものではありません。

Timerオブジェクトへの参照を保持しません。

これを変更してみてください:

private static Timer _timer;

これに:

private Timer _timer;

この:

var t = new Timer(OnTimeEvent, null, 1000, 1000);

これに:

_timer = new Timer(OnTimeEvent, null, 1000, 1000);
于 2012-11-19T14:19:53.403 に答える