В некотором смысле, SCM не может гарантировать, что исключение, которое вы начертите, не будет выбрано. Он не контролирует манипуляции с частным пользователем, например, если дополнительный служебный код влияет на _foo
.
Сказав это, не рассмотрим следующий сценарий, чтобы увидеть, почему ответ на ваш конкретный вопрос явно не:
1) Создайте свою службу со следующими изменениями, чтобы продемонстрировать:
public partial class MyService : ServiceBase
{
private Object _foo;
private const string _logName = "MyService Log.txt"; // to support added logging
public MyService()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
// demonstrative logging
var threadId = Thread.CurrentThread.ManagedThreadId;
using (var log = new StreamWriter(AppDomain.CurrentDomain.BaseDirectory + _logName, true))
{
log.WriteLine("{0}: In OnStart(string[]) on thread ID {1}. Sleeping for 10 seconds...", DateTime.Now, threadId);
}
// Sleep before initializing _foo to allow calling OnStop before OnStart completes unless the SCM synchronizes calls to the methods.
Thread.Sleep(10000);
_foo = new Object();
}
protected override void OnStop()
{
// demonstrative logging added
var threadId = Thread.CurrentThread.ManagedThreadId;
using (var log = new StreamWriter(AppDomain.CurrentDomain.BaseDirectory + _logName, true))
{
log.WriteLine("{0}: In OnStop() on thread ID {1}.", DateTime.Now, threadId);
}
if (_foo == null)
{
// demonstrative logging added
using (var log = new StreamWriter(AppDomain.CurrentDomain.BaseDirectory + _logName, true))
{
log.WriteLine("{0}: _foo == null", DateTime.Now);
}
throw new Exception("Assignment not visible"); // Can this happen?
}
_foo = null;
}
}
2) Откройте командную оболочку.
3) Откройте еще одну командную оболочку.
4) В первой командной оболочке установите службу (с sc create
), если вы еще этого не сделали, и запустите ее (с помощью net start
). Вы должны увидеть:
Служба MyService начинается .....
роспускного точек должны быть добавлены один за другим, как SCM ждет через 10 секунд сна, чтобы запустить службу.
5) Во второй командной оболочке попытайтесь остановить службу (с net stop
) до истечения 10 секунд. Вы должны увидеть:
Услуга запускается или останавливается. Пожалуйста, повторите попытку позже.
Таким образом, запуск службы - это операция блокировки, которая должна быть завершена до остановки службы.
6) Проверьте первую командную оболочку через 10 секунд. Вы должны увидеть:
Служба MyService была успешно запущена.
7) Вернитесь ко второй командной оболочке и попытайтесь снова остановить службу. Вы должны увидеть:
Служба MyService останавливается.
Служба MyService была успешно остановлена.
8) Обзор результирующий журнал - например:
10/22/2013 7:28:55 AM: В OnStart (строка []) на нити ID 4. Сон в течение 10 секунд ...
10/22/2013 7:29:17 AM: В OnStop() на нити ID 5.
Запуск и остановка службы быстро легче с двумя командными оболочками, я думаю; но пример работает аналогично с одной командной оболочкой.
Наконец, вы можете найти Mitchell Taylor (CoolDadTx) 's ответ a similar question in MSDN forums интересно, как я сделал:
потоковая модель используется SCM формально не задокументированы AFAIK. Известно, что каждая услуга вызывается в своем потоке. Однако SCM может использовать или не использовать пул потоков для повторного использования потока через службы. Когда вызывается услуга (запуск, остановка, пользовательские команды и т. Д.), Ожидается, что она выполнит свою задачу и вернется быстро. Существует ограничение на длительность этого срока. Что-то большее, чем быстрый возврат, требует, чтобы вы перенаправляли запрос на вторичный поток для обработки. Сам SCM работает на отдельном потоке, поэтому, если служба занимает слишком много времени, чтобы ответить, SCM видит, что он висел. Это обсуждается здесь: http://msdn.microsoft.com/en-us/library/ms684264(VS.85).aspx
UPDATE:
В частности, обратите внимание на статью MSDN Service State Transitions, к которой статья, в которой Mitchell Taylor приводит ссылки. Он содержит диаграмму состояния, которая довольно четко определяет & авторитетные документы, определяющие переходы состояния службы и выравнивание с тем, что я изложил выше. Он также объясняет в связи с диаграммой состояния, как SCM не передает запросы управления службами время от времени, чтобы обеспечить только определенные переходы состояния.
Меня интересуют также гарантии. Я никогда не видел, чтобы что-то вроде вашего примера вызывало проблему; однако, я знаю, что приобретение ресурсов, привязанных к идентичности потоков (в нашем случае мьютекса), вызвало мои проблемы с командой в прошлом. –
Я задал тот же вопрос раньше. Я выкопаю его. – spender
Здесь вы (обозначение как обман): [Calling ServiceBase.OnStart и OnStop ... тот же экземпляр?] (Http: // stackoverflow.com/questions/10799937/call-servicebase-onstart-and-onstop-same-instance) – spender