2013-07-10 37 views
2

我有这行代码一个严重的问题:如何处理呼叫这是容易挂在当前线程

new OdbcConnection(builder.ConnectionString)

我们的客户,每天晚上把他的DB2数据库停机备份,并有时这会导致我们的代码挂在这行代码中。即使在等待一个小时后仍然卡住。不幸的是,这个错误不能随意复制,只会随机出现几天。

有像这样的问题KB article at Microsoft但这种解决方法是不适用的,因为我们的MDAC的版本应该是新的。

我发现没有其他手段来解决这个问题,所以我要开始一个新的线程,让它尝试创建可在超时之后被杀害的对象。 我可以使用任务,但只能使用取消标记取消任务,因为任务由其中一行代码挂起或不挂起而不能评估。

在寻找如何中止任务,大家说,你不能中止任务,你不应该使用Thread.Abort的。

然而,在这种情况下,我没有看到任何其他的可能性莫过于此。任何人都可以提出一个更好的方式来处理这个挂起的代码?

+0

如何清理一下就可以了,你实例化进程的另一个副本,并立即强行终止当前与Environment.Exit?新的实例将运行起来,并找到数据库不可用,可能会定期重试,直到数据库确实出现,然后正常运行(直到下一次挂断:)。 –

+0

这只是挂起的许多工作之一。所以我不能随意重启服务。而且我仍然需要一个控制实例。 – Zebi

回答

-1

好像只是开始一个新的线程,因为那里是挂起代码将只会加重你的问题的条件,它肯定不是一个线程的目的。我会建议一个Try/Catch/Finally块来防止代码挂起。

+1

Try/Catch/Finally可能根本没有帮助。如果呼叫阻塞,Catch/Finally将不会被执行。 –

+0

这是正确的尝试/捕获将无法正常工作。 – Zebi

1

所以在这里不建议,我拿到这个问题是:

private OdbcConnection ResolveConnection(OdbcConnectionStringBuilder connectionString) 
{ 
    if (!_connections.ContainsKey(connectionString.Dsn)) 
    { 
     OdbcConnection connection = null; 

     var newOdbcConnectionTimeout = TimeSpan.FromSeconds(30); 
     var evt = new ManualResetEvent(false); 

     var connectionThread = new Thread(() => 
      { 
       try 
       { 
        connection = new OdbcConnection(connectionString.ConnectionString); 
       } 
       finally 
       { 
        evt.Set(); 
       } 
      }); 
     connectionThread.Start(); 
     var isOk = evt.WaitOne(newOdbcConnectionTimeout); 

     if (!isOk || connection == null) 
     { 
      connectionThread.Abort(); 
      const string messageFormat = "Timeout of {0} reached while creating OdbcConnection to {1}."; 
      throw new InvalidOperationException(string.Format(messageFormat, newOdbcConnectionTimeout, connectionString)); 
     } 

     _connections.Add(connectionString.Dsn, connection); 
    } 

    return _connections[connectionString.Dsn]; 
} 
+0

这是如何为你工作的? –

+0

对不起,我不记得了。这是4年前:( – Zebi

相关问题