连接池使用相同的错误连接字符串向两个线程返回相同的异常实例吗? [英] Connection Pool returns Same Exception Instance to Two Threads Using the Same Bad Connection String?

查看:34
本文介绍了连接池使用相同的错误连接字符串向两个线程返回相同的异常实例吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好吧,这看起来像是.NET中的主要基本错误:

Ok this looks like a major fundamental bug in .NET:

请考虑以下简单程序,该程序有意尝试连接到不存在的数据库:

Consider the following simple program, which purposely tries to connect to a non-existent database:

class Program
{
    static void Main(string[] args)
    {            

        Thread threadOne = new Thread(GetConnectionOne);
        Thread threadTwo = new Thread(GetConnectionTwo);            
        threadOne.Start();
        threadTwo.Start();

    }



    static void GetConnectionOne()
    {
        try
        {
            using (SqlConnection conn = new SqlConnection("Data Source=.\\wfea;Initial Catalog=zc;Persist Security Info=True;Trusted_Connection=yes;"))
            {
                conn.Open();
            }    
        } catch (Exception e)
        {
            File.AppendAllText("ConnectionOneError.txt", e.Message + "\n" + e.StackTrace + "\n");
        }

    }


    static void GetConnectionTwo()
    {
        try
        {
            using (SqlConnection conn = new SqlConnection("Data Source=.\\wfea;Initial Catalog=zc;Persist Security Info=True;Trusted_Connection=yes;"))
            {
                conn.Open();
            }
        }
        catch (Exception e)
        {
            File.AppendAllText("ConnectionTwoError.txt", e.Message + "\n" + e.StackTrace + "\n");
        }

    }
}

运行此程序并在catch块上设置断点.DBConnection对象将尝试连接15秒(在两个线程上),然后将引发错误.检查异常的堆栈跟踪,堆栈跟踪将混合两个调用堆栈,如下所示:

Run this program and set breakpoints on the catch blocks. The DBConnection object will attempt to connect for 15 seconds (on both threads), then it will throw an error. Inspect the exception's stack trace, and the stack trace will have TWO call stacks intermingled, as follows:

at System.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject)
at System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection)
at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
at System.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject)
at System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnection owningObject)
at System.Data.SqlClient.SqlConnection.Open()
at ZoCom2Test.Program.GetConnectionOne() in C:\src\trunk\ZTest\Program.cs:line 38
at System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection)
at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
at System.Data.SqlClient.SqlConnection.Open()
at ZoCom2Test.Program.GetConnectionTwo() in C:\src\trunk\ZTest\Program.cs:line 54

您可能必须尝试几次才能使这种情况发生,但是我现在正在我的机器上使这种情况发生.这怎么可能?在VM级别,这应该是完全不可能的.看起来DBConnection.Open()函数同时在两个线程上同时抛出相同的异常,或者类似的事情.

You may have to try it several times to get this to happen, but I'm getting this to happen right now on my machine. How is this possible? This should be totally impossible at the VM level. It looks like the DBConnection.Open() function is simultaneously throwing the same exception on two threads at once, or something bizarre like that.

推荐答案

试试看,看看会发生什么:

Try this instead, and see what happens:

class ThreadingBug
{
    private const string CONNECTION_STRING =
        "Data Source=.\\wfea;Initial Catalog=catalog;Persist Security Info=True;Trusted_Connection=yes;";

    static void Main(string[] args)
    {
        try
        {
            Thread threadOne = new Thread(GetConnectionOne);
            Thread threadTwo = new Thread(GetConnectionTwo);
            threadOne.Start();
            threadTwo.Start();

            threadOne.Join(2000);
            threadTwo.Join(2000);
        }
        catch (Exception e)
        {
            File.AppendAllText("Main.txt", e.ToString());
        }
    }

    static void GetConnectionOne()
    {
        try
        {
            using (SqlConnection conn = new SqlConnection(CONNECTION_STRING))
            {
                conn.Open();
            }
        }
        catch (Exception e)
        {
            File.AppendAllText("GetConnectionOne.txt", e.ToString());
        }
    }

    static void GetConnectionTwo()
    {
        try
        {
            using (SqlConnection conn = new SqlConnection(CONNECTION_STRING))
            {
                conn.Open();
            }
        }
        catch (Exception e)
        {
            File.AppendAllText("GetConnectionTwo.txt", e.ToString());
        }
    }
}


我相信这里有一个错误,尽管它既不是主要错误,也不是基本错误.在努力缩小范围(并执行删除一个线程之类的操作)之后,似乎两个线程上的连接池实现都抛出了 Exception 类的同一实例(对发现的Gregory表示敬意)这).有时这会显示为损坏的(混合的")堆栈跟踪,有时甚至会显示为两个线程上的同一堆栈跟踪,即使两个线程之间的代码完全不同.


I believe there is a bug here, though it's neither major, nor fundamental. After working to narrow this down (and to do things like removing one thread), it looks like the same instance of the Exception class is thrown by the Connection Pool implementation on both threads (kudos to Gregory for discovering this). This sometimes shows up as a corrupt ("intermingled") stack trace, and sometimes simply as the same stack trace on both threads, even when the code is quite different between the two threads.

注释掉 Thread.Start 调用之一显示了一个完全不同的堆栈跟踪,表明奇数部分在连接池实现中-连接池正在分发奇数堆栈跟踪,因为两个线程使用相同的连接字符串和凭据.

Commenting out one of the Thread.Start calls shows an entirely different stack trace, demonstrating that the odd part is in the connection pool implementation - the odd stack traces are being handed out by the connection pool, since both threads use the same connection string and credentials.

我已经在 https:/上提交了一个Connect问题./connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=522506 .每个人都应该对自己的重要性(或不重要),是否可以复制它或是否有解决方法进行自由投票.这将有助于Microsoft确定优先级.

I've submitted a Connect issue on this at https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=522506. Everyone should feel free to vote on how important (or unimportant) you feel it is, whether you can reproduce it, or whether you have a workaround. This will help Microsoft prioritize a fix.

更新:连接"问题已更新.Microsoft承认它是一个错误,并计划在将来的版本中对其进行修复.

Update: The Connect issue has been updated. Microsoft acknowledges it as a bug, and plans to fix it in a future release.

感谢nganju,Gregory和其他参与解决此问题的人.确实是一个错误,它将得到修复,这是因为我们.

Thanks to nganju, Gregory, and everyone else who participated in solving this problem. It was indeed a bug, and it will be fixed, and it's because of us.

这篇关于连接池使用相同的错误连接字符串向两个线程返回相同的异常实例吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆