如何处理容易挂断当前线程的呼叫

本文关键字:前线 线程 呼叫 易挂断 何处理 处理 | 更新日期: 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块来防止代码挂起。