0

アプリがデータベース サーバーに接続して一部のデータを取得しようとすると、例外が発生することがあり、例外が処理された場合でも例外が発生すると、デッド スレッドが残るように見えます。そのため、約 300 のスレッドがサービスをダウンさせています。

タイマーで定期的に呼び出されるコードは次のとおりです。

Parallel.ForEach(dbs, pair =>
        {
            db l = pair.Value;

            if (String.IsNullOrEmpty(l.city))
                l.city = l.configCity;

            using (OracleConnection conn = new OracleConnection(l.connString))
            {
                try
                {                        
                    conn.Open();
                }
                catch (Exception exc)
                {
                    Console.WriteLine(String.Format("({0}, {1}): {2}{3}", l.connAlias, l.lid, exc.Message, Environment.NewLine));                        
                }

                try
                {
                    if ((conn != null) && (conn.State == ConnectionState.Open))
                    {        
                        // This method just call stored procedure and then set received data to 'l' object                    
                        if (!DbConnection.SetBadicData(conn, ref l))
                        {
                            Console.WriteLine(String.Format("Couldn't refresh basic data on ({0}, {1})", l.connAlias, l.id));
                        }                            

                        // This method also just call procedure and set received data to object
                        if (!DbConnection.SetExtendedData(conn, ref l))
                        {
                            Console.WriteLine(String.Format("Couldn't refresh advanced data on ({0}, {1})", l.connAlias, l.lid));
                        }
                    }
                }
                catch (Exception exc)
                {
                    Console.WriteLine(String.Format("({0}, {1}): {2}{3}", l.connAlias, l.lid, exc.Message, Environment.NewLine));
                }
            }

        });

例外は次のとおりです。

  • 保護されたメモリを読み書きしようとしました。これは多くの場合、他のメモリが破損していることを示しています
  • Oracle クライアントの内部例外
  • SEHException - 外部コンポーネントが例外をスローしました

データベースへの接続に使用されるコンポーネントは、devArt dotConnect for Oracleです。

どうすればそれを管理できますか?BeginConnectそして、強制的な休憩EndConnectは助けになりますか?

4

1 に答える 1

1

固定ライブラリを入手してください:-)

しかし、真剣に。使用する必要があり、変更できず、バグのあるサードパーティのライブラリがある場合、私が見る唯一の方法は、別の AppDomain で実行することです。ドメイン間の通信は、単にメソッドを呼び出すよりも困難ですが、それでも比較的簡単です。たとえば、WCF サービス (名前付きパイプを使用) を使用して通信できます。

厄介なライブラリを別の AppDomain で処理するコードを作成したら、そのドメインを定期的に、または他の条件下でリサイクル (破棄して再作成) できます。これにより、ぶら下がっているスレッド、解放されていないオブジェクトなどがすべて殺されます。

これは回避策のタイプのソリューションですが、少なくともこれを回避する方法を提供する必要があります。

于 2012-02-17T16:05:26.530 に答える