2

このコード行には重大な問題があります。

new OdbcConnection(builder.ConnectionString)

私たちの顧客は毎晩 DB2 データベースをダウンさせてバックアップしているため、コードがこのコード行でハングすることがあります。1時間待っても固まります。残念ながら、このエラーは自由に再現することはできず、ランダムに数日しか発生しません。

このような問題に関する Microsoft の KB 記事がありますが、MDAC のバージョンの方が新しいため、この修正は適用されません。

問題を解決する他の方法が見つからなかったので、新しいスレッドを開始して、タイムアウト後に強制終了できるオブジェクトを作成しようとしました。タスクを使用できますが、タスクはハングするかどうかに関係なく 1 行のコードで構成されているため、評価できないキャンセル トークンでのみタスクをキャンセルできます。

タスクを中止する方法を検索しているときに、タスクを中止することはできず、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 に答える