如何解决不良模式关闭线程追逐(重新)启动线程

本文关键字:线程 重新 启动 追逐 不良 何解决 解决 模式 | 更新日期: 2023-09-27 17:53:23

容错线程的奇怪模式,并及时关闭它们。注意到这种模式在产品中反复出现。

假设你有一个容错进程——一个网络连接——抛出SSL,或者一个WMI连接和查询,或者一个数据库连接和查询等等。

您的网络客户端连接失败时将等待片刻(假设5分钟),然后尝试重新连接。

现在,有时当这种情况发生时,您可能也想要停止网络,这会带来第二个线程信号,表示它正在停止并执行一些关闭。

如果容错进程正在等待,那么通过让它等待另一个线程管理的事件来杀死它是很容易的。

您如何在中途停止Connect函数,因为它具有长/昂贵的过程?如何在Cancel()调用之后/期间管理Connect()中的步骤,现在可以在连接创建新SslStream的过程中调用取消/清理,从而成功地完成连接,并将不完整的状态- m_network设置为新对象。

private TcpClient m_network = new TcpClient();
private ManualResetEvent m_closing = new ManualResetEvent(true);
private void Connect()
{
    try
    {
        m_network.Connect(m_config.Address.Host, m_config.Address.Port);
        SslStream sslStream = new SslStream(m_network.GetStream(), true, ValidateServerCertificate, ClientCertificateSelection );
        X509CertificateCollection clientCertificates = GetClientCertificates();
        sslStream.AuthenticateAsClient(m_config.Address.Host, clientCertificates, SslProtocols.Default, false );
        // do more stuff in a new thread
    }
    catch (System.Exception ex)
    { Reset(); }
}
public void BeginExecution()
{
    ThreadPool.QueueUserWorkItem(delegate
    {
        m_closing.Reset();
        Connect();
    });
}
public void Cancel()
{
    m_closing.Set();
    Cleanup();
}
private void Cleanup()
{
    TcpClient tempClient = m_network;
    m_network = new TcpClient();
    if (tempClient.Connected)
    {
        tempClient.Close();
    }
}
void Reset(){
    if (m_closing.WaitOne(0))
        return;
    Cleanup();
    if (m_closing.WaitOne(TimeSpan.FromSeconds(300)))
        return;
    ThreadPool.QueueUserWorkItem(delegate { Connect(); });
}

设置Connect为锁或使用本地网络变量会破坏试图尽早终止它的目的。

在Connect中的每个操作之后都检查事件,然后调用Cleanup,这似乎很难看。

如何解决不良模式关闭线程追逐(重新)启动线程

f#中的异步块或c#中的异步CTP的好处是——您可以外部化取消和超时流的处理。如果需要,您可以对TPL和延续执行类似的操作。