gpt4 book ai didi

c# - 从线程调用 .net 服务中的停止时如何避免死锁?

转载 作者:行者123 更新时间:2023-11-30 14:46:22 24 4
gpt4 key购买 nike

我有一个线程用于读取 TCP 套接字;我从服务器收到一条消息,要求我执行自动更新。所以,现在读取线程必须调用servicebase Stop() 来触发OnStop() 函数。但是,读取线程必须连接到主线程才能正确终止服务。所以现在 OnStop() 函数正在等待读取线程加入,但读取线程无法加入,因为它正在等待 Stop() 函数完成运行。

所以基本上它看起来像这样:

public void Start()
{
OnStart(new string[0]);
}

protected override void OnStart(string[] args)
{
stopEventRecv = new AutoResetEvent(false);
RecvThread = new Thread(RecvLoop);
RecvThread.Start();
}

protected override void OnStop()
{
// Doesn't matter because we are about to deadlock
stopEventRecv.Set();
// Dead lock
RecvThread.Join();
}

private void RecvLoop(object arg)
{
while (true)
{
if (stopEventRecv.WaitOne(5000))
{
return;
}

if (!IsConnected())
continue;

// here we get message from server saying to Stop so
// the message is processed and uses a callback where
// ServiceBase.Stop() is called.
// The reason for the callback isn't relevant to the
// question I don't think but i'm mentioning it in case.
// For the sake of the question I'll just call Stop()
// here to demonstrate the problem.
Stop();
}
}

我该如何解决这个问题?是否需要在退出服务前加入所有线程?在这里用 Abort 代替 join 可以吗?

最佳答案

服务控制管理器 (SCM) 负责向服务发送命令以告知它们开始、停止、暂停以及您选择定义的任何自定义命令。

您编写 OnXxx 方法来响应 SCM 发送给您的服务的命令。为了正确启动停止,您应该要求 SCM 停止您的服务,您可以使用 ServiceController 来做到这一点。类的 Stop 方法。这会启动停止但不会等待它完成。


这可以确保 SCM 知道您的服务是故意停止的,而不是因为任何其他原因而退出的。这很重要,因为如果为您的服务配置了任何恢复操作,您不希望它们在这种情况下发生。

关于c# - 从线程调用 .net 服务中的停止时如何避免死锁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49254146/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com