2

我对这行代码有一个严重的问题:

new OdbcConnection(builder.ConnectionString)

我们的客户每晚都会关闭他的 DB2 数据库来备份它,有时这会导致我们的代码在这行代码处挂起。即使等了一个小时,它仍然卡住了。不幸的是,这个错误不能随意复制,只会随机发生几天。

Microsoft有一篇关于此类问题的知识库文章,但此修复不适用,因为我们的 MDAC 版本应该更新。

我发现没有其他方法可以解决这个问题,所以我想启动一个新线程,让它尝试创建可以在超时后被杀死的对象。我可以使用任务,但只能使用无法评估的取消令牌取消任务,因为任务由一行代码组成,它要么挂起要么不挂起。

在搜索如何中止任务时,每个人都说您不能中止任务并且您不应该使用 Thread.Abort。

但是在这种情况下,我没有看到除此之外的任何其他可能性。任何人都可以提出更好的方法来处理这个挂起的代码吗?

4

2 回答 2

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];
}
于 2013-07-11T08:26:42.463 回答
-1

似乎只是因为有一个挂起代码的条件而开始一个新线程只会使您的问题更加复杂,而且这肯定不是线程的目的。我建议使用 Try/Catch/Finally 块来防止代码挂起。

于 2013-07-10T15:50:42.380 回答