Why won't my solution work to P/Invoke NotifyServiceStatusChange in C#?

后端 未结 3 1919
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-18 14:26

I am trying to P/Invoke the NotifyServiceStatusChange event in C# to check when a service has stopped. I managed to get it to compile and run without any errors, but now,

3条回答
  •  眼角桃花
    2020-12-18 14:33

    Read related question here: http://social.msdn.microsoft.com/Forums/vstudio/en-US/f68fb826-036a-4b9c-81e6-4cbd87931feb/notifyservicestatuschange-not-working-in-c-for-windows-service-notification

    Important quote: "the system invokes the specified callback function as an asynchronous procedure call (APC) queued to the calling thread. The calling thread must enter an alertable wait"

    I don't remember whether .NET framework 4 uses alertable waiting when you enter Thread.Sleep or some form of Wait on waithandles, even though it uses alertable waiting for asynchronous I/O, for internal timer threads etc.

    However just try Thread.Sleep or some flavor of Wait on some waithandle, instead of Console.ReadLine, make sure that your thread is blocked by those APIs at the time when you kill the service. This might do the magic - but, to my knowledge, this is a dangerous way, because .NET runtime does not expect user code to be executed on an APC. At least, try not to use NET framework resources or absolutely any APIs (especially synchronization-related or memory allocation) directly from your callback - just set some primitive variable and quit.

    With APCs, the safest solution for you would be to have the callback implemented in some kind of native module, and also scheduled from some non-.NET thread, interoperating with managed code through shared variables, a pipe, or COM interface.

    Or, as Hans Passant suggested in another copy of your question, just do polling from managed code. Absolutely safe, easy to implement, guaranteed to work.

    Excellent source of relevant information is Joe Duffy's book (he covers a lot of topics, and alertable waits and .NET in particular): http://www.amazon.com/Concurrent-Programming-Windows-Joe-Duffy/dp/032143482X

    UPDATE: Just consulted with Joe Duffy's book, yes indeed, scheduling .NET code on an APC may result in deadlocks, access violations and generally unpredictable behavior. So the answer is simple: don't do APC from a managed thread.

提交回复
热议问题