1

我正在编写一个在 .NET 3.5 上运行的 C# Windows 窗体应用程序,并使用 Oracle 的客户端连接到数据库(我希望我可以升级到 .NET 4.0 或更高版本,但我不能)。应用程序中有很多遵循通常模式的代码;这是伪代码:

var worker = new BackgroundWorker();
worker.DoWork += worker_DoWork;
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
worker.RunWorkerAsync();

...

private void worker_DoWork(object sender, DoWorkEventArgs e) {
    using(var conn = OpenOracleConnection()) {
        e.Result = LoadSomethingFromDatabase(conn);
    }
}

private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
    DisplayLoadedData(e.Result);
}

到目前为止,一切都很好。不幸的是,我最近添加了一些非常快速地执行此类查询的代码,尽管只在单个线程上。现在,应用程序偶尔会出现以下两种行为之一:

  • 它锁定在 Oracle 代码中的某个位置,使用完全无害的方法,例如"reader.GetInt32(string)".
  • 它使整个 CLR 崩溃。我能捕捉到的也不例外;整个过程立即死亡。在事件查看器中,Oracle 的 DLL 被列为故障模块。

我检查了一下,据我所知,我的网络连接或 Oracle DB 本身没有任何问题。我也没有跨线程共享我的 Oracle 连接;虽然 worker.DoWork 中的代码在 ThreadPool 的后台线程上运行,但该特定的“conn”实例一次只能从一个线程访问(因为它在线程上运行的方法中被声明为局部变量) .

有没有人对我如何解决这个问题有任何想法,或者至少调试它?它曾经发生在其他人身上吗?

更新:为了它的价值,我将我的实现切换为对每个工作线程使用单个长时间运行的数据库连接,并限制工作线程的数量。这大大降低了这个问题出现的频率,尽管遗憾的是它并没有完全消除这个问题。

4

0 回答 0