在我的windows服务中,我启动了5个独立工作的线程,这些线程不编写公共资源(因此没有互斥或死锁)。
但是有一个线程有一个AutoResetEvent _waitTillUSBInsterted.WaitOne()调用。基本上,该线程负责在插入USB后立即启动USB文件传输,因此它等待直到从负责监视USB插入/删除事件的线程接收到通知信号(通过设置_waitTillUSBInsterted即通过调用_waitTillUSBInsterted.Set())。
问题:会不会因为_waitTillUSBInsterted.WaitOne()而停止我的windows服务?
询问原因:I试图通过windows服务管理器工具(通过按下" stop ")停止windows服务,但它无法停止该服务(获得了错误1053)。我终于不得不重新启动我的电脑了。一次又一次地发生(4-5次)。我注释掉了所有线程--启动调用,然后是--我能够停止我的windows服务;,我取消了所有线程的注释--逐个启动调用,但现在我能够停止windows服务(不做任何更改)。我无法复制这种情况,但我怀疑_waitTillUSBInsterted.WaitOne()可能是原因。
发布于 2017-04-05 13:56:10
如果您的线程是前台线程,并且不使用EventWaitHandle.WaitOne(Int32),那么是的:线程是一个前台线程,它阻止进程终止,直到线程终止,WaitOne()阻止线程终止,从而阻止它终止。
来自System.Threading.Thread.IsBackground
线程要么是后台线程,要么是前台线程。后台线程与前台线程相同,但后台线程不会阻止进程终止。一旦进程的所有前台线程都结束了,公共语言运行库就会结束该进程。任何剩余的后台线程都会停止,并且不完成。默认情况下,以下线程在前台执行(即它们的IsBackground属性返回false):
任何通过使用线程构造函数创建的线程,除非通过使用IsBackground属性进行专门配置,否则都将是前台线程,并将阻止进程终止直到进程终止。
来自System.Threading.WaitHandle.WaitOne()
阻塞当前线程,直到当前WaitHandle接收到信号为止。
有几种方法可以缓解这个问题。首先:如果可以让线程过早终止,那么就像这样构造线程:
var thread = new Thread(ThreadStart)
{
IsBackground = true
}当服务终止时,尽管线程阻塞了WaitHandle.WaitOne()调用,进程仍将正确退出。
第二种方法是使用某种类型的状态,通过引用传递,通知线程它应该终止。下面的示例使用CancellationToken。
using System.ServiceProcess;
using System.Threading;
public class ServiceState
{
public ServiceState(CancellationToken cancellationToken, WaitHandle waitHandle)
{
this.CancellationToken = cancellationToken;
this.WaitHandle = waitHandle;
}
public CancellationToken CancellationToken { get; }
public WaitHandle WaitHandle { get; }
}
public class MyService : ServiceBase
{
private readonly Thread serviceThread;
private readonly CancellationTokenSource cancellationTokenSource;
private readonly WaitHandle waitHandle;
public Service()
{
serviceThread = new Thread(ThreadProc);
cancellationTokenSource = new CancellationTokenSource();
waitHandle = new EventWaitHandle(false, EventResetMode.AutoReset);
}
protected override void OnStart(string[] args)
{
var state = new ServiceState(cancellationTokenSource.Token, waitHandle);
serviceThread.Start(state);
}
protected override void OnStop()
{
cancellationTokenSource.Cancel();
waitHandle.Set();
}
private static void ThreadProc(object state)
{
var serviceState = (ServiceState)state;
do
{
serviceState.WaitHandle.WaitOne();
if (serviceState.CancellationToken.IsCancellationRequested)
{
return; // This will terminate the thread.
}
// Thread logic goes here.
} while (true);
}
}https://stackoverflow.com/questions/43232701
复制相似问题