3dparty 组件留下死线程
当应用程序尝试连接到数据库服务器并检索一些数据时,它有时会引发异常,并且即使在处理异常时,它似乎也会在引发异常时留下死线程。因此大约有 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
强制中断会有帮助吗?
While an app tries to connect to database server and retrieve some data, it sometimes raise an exception and it seems like it leaves dead threads when expcetion raised even when it's handled. So there are about 300 threads that getting service down.
Here is code invoked periodically on timer:
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));
}
}
});
Exceptions are:
- Attempted to read or write protected memory. This is often an
indication that other memory is corrupt - Internal exception in Oracle client
- SEHException - External component has thrown an exception
Component that used to connect to database is devArt dotConnect for Oracle.
How can I manage it guys? Does BeginConnect
and then forced breaking by EndConnect
will help?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
得到一个固定的库:-)
但是说真的。如果您有必须使用的第三方库,无法更改它并且存在错误,我看到的唯一方法是在单独的 AppDomain 中运行它。域之间的通信比仅仅调用方法更困难,但仍然相对容易。例如,您可以使用 WCF 服务(带有命名管道)进行通信。
一旦您的代码在单独的 AppDomain 中处理令人讨厌的库,您就可以定期或在其他条件下回收(销毁和重新创建)该域。这将杀死所有挂起的线程、未释放的对象等。
这是一种解决方案类型,但它至少应该为您提供解决此问题的方法。
Get a fixed library :-)
But seriously. If you have a third party library that you have to use, cannot change it and which is buggy, the only way I see is to run it in a separate AppDomain. Communication between domains is more difficult than just calling a method but still relatively easy. You can for example use a WCF service (with named pipe) to communicate.
Once you have your code handling nasty library in a separate AppDomain, you can recycle (destroy and recreate) that domain periodically or under other conditions. That will kill off all hanging threads, unreleased objects etc.
It is a workaround type of solution but it should give you at least a way out of this.