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 回答