如何处理容易挂断当前线程的呼叫
本文关键字:前线 线程 呼叫 易挂断 何处理 处理 | 更新日期: 2023-09-27 18:22:00
我对这行代码有一个严重的问题:
new OdbcConnection(builder.ConnectionString)
我们的客户每天晚上都会取下他的DB2数据库进行备份,有时这会导致我们的代码挂在这行代码上。即使等了一个小时,它仍然卡住了。不幸的是,这个错误不能随意复制,只会随机出现几天。
Microsoft有一篇关于此类问题的知识库文章,但此修复程序不适用,因为我们的MDAC版本应该更新。
我找不到其他方法来解决这个问题,所以我想启动一个新的线程,让它尝试创建一个可以在超时后杀死的对象。我可以使用Tasks,但任务只能使用取消令牌来取消,该令牌无法评估,因为task由一行代码组成,它要么挂起,要么不挂起。
在搜索如何中止任务时,每个人都说你不能中止任务,也不应该使用Thread.Artr.
然而,在这种情况下,我看不出其他任何可能性。有人能提出一个更好的方法来处理这个挂起的代码吗?
所以这里没有建议,我对这个问题的看法是:
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];
}
这似乎只是因为存在挂起代码的条件而启动一个新线程,这只会加剧问题,当然这不是线程的目的。我建议使用Try/Catch/Finally块来防止代码挂起。