如何处理容易挂起当前线程的调用

时间:2013-07-10 15:31:18

标签: c# multithreading db2 odbc hang

我对这行代码存在严重问题:

new OdbcConnection(builder.ConnectionString)

我们的客户每晚都会将他的DB2数据库关闭以备份它,有时这会导致我们的代码挂在这行代码中。即使经过一个小时的等待,它仍然停滞不前。不幸的是,这个错误无法随意复制,只能在几天内随机发生。

这样的问题有KB article at Microsoft,但此修复程序不适用,因为我们的MDAC版本应该更新。

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

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

然而在这种情况下,我没有看到任何其他可能性。任何人都可以建议更好的方法来处理这个悬挂代码吗?

2 个答案:

答案 0 :(得分: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];
}

答案 1 :(得分:-1)

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