C# 如何解决不良模式关闭线程追逐(重新)启动线程
容错线程的奇怪模式,并及时关闭它们。注意到这种模式在产品中反复出现 假设您有一个容错进程—网络连接—也可以加入SSL,或者WMI连接和查询,或者数据库连接和查询等 当网络客户端连接失败时,将等待片刻(比方说5分钟),然后尝试重新连接 现在,有时当这种情况发生时,您可能还想停止联网,这会带来第二个线程,表示它正在停止并执行一些关机操作 如果容错进程正在等待,那么让它等待另一个线程管理的事件就很容易终止 您将如何中途停止Connect功能,因为它的流程很长/成本很高?如何管理C# 如何解决不良模式关闭线程追逐(重新)启动线程,c#,.net,design-patterns,C#,.net,Design Patterns,容错线程的奇怪模式,并及时关闭它们。注意到这种模式在产品中反复出现 假设您有一个容错进程—网络连接—也可以加入SSL,或者WMI连接和查询,或者数据库连接和查询等 当网络客户端连接失败时,将等待片刻(比方说5分钟),然后尝试重新连接 现在,有时当这种情况发生时,您可能还想停止联网,这会带来第二个线程,表示它正在停止并执行一些关机操作 如果容错进程正在等待,那么让它等待另一个线程管理的事件就很容易终止 您将如何中途停止Connect功能,因为它的流程很长/成本很高?如何管理Connect()调用C
Connect()
调用Cancel()
后/调用过程中的步骤,此时可以在Connect正在创建新的ssl流的过程中调用Cancel/Cleanup,从而成功完成连接,并将未完成状态-m_网络设置为新对象
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中的每个操作之后一直检查事件,然后调用Cleanup,这看起来很糟糕。F#中的异步块或C#is的异步CTP的好处是——可以将取消和超时流的处理外部化。如果必须的话,您可以在TPL和continuations上做类似的事情。这里有机会使用F吗?Acthc CTP怎么样?为了更详细地回答你的问题,考虑重新标记它。@ GRGC:谢谢,异步CTP看起来很有趣,虽然在框架2中不可用。现在还不可能。你是说你只限于.NETFramework2.0吗?如果您使用的是4.0,那么可以使用Task Parallel Library和ContinueWith来实现与CTP中的async block相同的效果:唯一的区别是代码必须向后编写。