4

Similar (if not same question as) Network path not found exception encountered randomly, but I have code to reproduce the issue so I want to ask again as it appears to be a real issue independent of hardware and can be reproduced.

Here's the error:

provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server) ---> System.ComponentModel.Win32Exception (0x80004005): The network path was not found at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection) at System.Data.ProviderBase.DbConnectionPool.WaitForPendingOpen()

To reproduce this I created a console application that's run every minute (we also have a Dapper DAL test, hence the parameter):

internal class Program
{
    private static int _totalOpenConnections;
    private static readonly Stopwatch Timer = new Stopwatch();
    private static bool _hasError;

    private static int Main(string[] args)
    {
        var list = Enumerable.Range(1, Settings.Default.TotalCommandsToExecute);

        // simple ADO.NET test
        if (args.Length > 0 && args[0].Equals("ado", StringComparison.OrdinalIgnoreCase))
        {
            Console.WriteLine("Beginning ADO.NET Test...");

            Timer.Restart();

            Parallel.ForEach(list, new ParallelOptions {MaxDegreeOfParallelism = Settings.Default.ConcurrentCount},
                i => AsyncContext.Run(async () =>
                {
                    try
                    {
                        PrintStatus(i);
                        await TestADONet();
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.ToString());
                        _hasError = true;
                    }
                }));

            Timer.Stop();

            Console.WriteLine($"Completed ADO.NET Test in {Timer.ElapsedMilliseconds} ms");
        }

        if (_hasError)
            return 1;
        return 0;
    }

    private static void PrintStatus(int index)
    {
        Console.WriteLine(
            $"Started: {index} of {Settings.Default.TotalCommandsToExecute}\tCurrently Open: {_totalOpenConnections}");
    }

    private static async Task TestADONet()
    {
        using (var conn = new SqlConnection(Settings.Default.TestConnection))
        {
            await conn.OpenAsync();
            Interlocked.Increment(ref _totalOpenConnections);

            var command = new SqlCommand("SELECT 1 Field1, 2 Field2, 3 Field3", conn);
            var reader = await command.ExecuteReaderAsync();
            while (reader.Read())
            {
                var result = new TestEntity
                {
                    Field1 = reader.GetInt32(0),
                    Field2 = reader.GetInt32(1),
                    Field3 = reader.GetInt32(2)
                };
            }
        }
        Interlocked.Decrement(ref _totalOpenConnections);
    }

    public class TestEntity
    {
        public int Field1 { get; set; }

        public int Field2 { get; set; }

        public int Field3 { get; set; }
    }
}

The application settings ConcurrentCount = 100, and TotalCommandsToExecute = 200. The idea is to hit the connection pool pretty hard with async commands in parallel.

This application reproduces it, however, it's also occurred in production in console applications, web applications (ASP.NET MVC, and ASP.NET WebForms).

It also occurs rather randomly. We've had Rackspace and some DBAs crawl through the environment on the issue to no avail, which led to this application - which reproduced it in the development environment.

The connection string is rather bland, of the form "Data Source=;Database=;User Id=;Password="

SQL Server 2014, but this has occurred against two separate servers (dev/rackspace)

The query in the test is intentionally benign

"SELECT 1 Field1, 2 Field2, 3 Field3"

The test does use Nito.AsyncEx, the only none System assembly in use here, to get async support. Again the issue occurs in other applications not using this assembly, so I don't think it's an issue - let me know if not and I'll reproduce it another way.

ANY ideas greatly appreciated!

4

1 Answer 1

5

The issue was with named pipes. It might be expressed more within a VM (speculation from the links below). Using TCP/IP by adding tcp: within the connection string and specifying the port resolved the issue.

Some related cases:

  1. https://dba.stackexchange.com/questions/24165/sql-server-should-we-use-tcp-or-named-pipes-or-use-the-default
  2. http://devproconnections.com/database-development/sql-server-performance-tip-favoring-tcpip-over-named-pipes
  3. https://serverfault.com/questions/30955/sporatic-connection-issues-connecting-to-sql-2005-named-pipes-vs-tcp-ip-issue/31024#31024
  4. https://dba.stackexchange.com/questions/29106/named-pipes-connection-closed-when-subjected-to-load

Conclusion, always use TCP/IP explicitly unless the SQL Server is on the same machine. You can configure the SQL Server to not accept named pipes as well, but going forward I will just be adding it to my connection strings as well.

Not the answer you're looking for? Browse other questions tagged or ask your own question.