2015-03-22 4 views
2

Я экспериментирую с выполнением асинхронного запроса в течение некоторого времени. Моя цель заключается в выполнении простых операторов SQL и не ждет их завершения. Нижеприведенный код работает хорошо для 10, 500 или 1000 или даже 5000 запросов. но для 50000 запросов внезапно возникает ошибка и говоритADONET async execute - connection broken error

«BeginExecuteReader требует открытого и доступного соединения. Текущее состояние соединения открыто». , и иногда он говорит: «... состояние: сломан»

Это тестовый сайт aspnet, и я думаю, что может случиться 50 000 запросов. это что-то мне не хватает? не должно ли это работать?

Я использую windows7 x64, и я верю его что-то todo с лимитами опроса соединения sql. вы, возможно, скажете, что 50 000 слишком велико, но мне нужно избежать этой ошибки, чтобы доверять коду, и я не знаю, как это сделать.

ps: В коде я открываю соединение, но не закрываю его для целей тестирования. если я закрываю функцию обратного вызова соединения, она никогда не срабатывает.

любые предложения? И не так много информации об этой ошибке в google.

Partial Class test 
    Inherits System.Web.UI.Page 

    Dim cnTest As SqlConnection 

    Protected Sub cmdAsyncTest_Click(sender As Object, e As EventArgs) Handles cmdAsyncTest.Click 

     Dim s As String = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 
     Dim sqlstr As String 
     Dim x1 As Integer, x2 As Integer, i As Integer 

     sqlstr = "INSERT INTO test1 (name,surname,a2) VALUES ('" & s & "','" & s & "',5)" 

     Dim cnstr As String = System.Configuration.ConfigurationManager.ConnectionStrings("ConnectionStringLOG").ConnectionString 
     cnTest = New SqlConnection(cnstr) 
     cnTest.Open() 

     watch = Stopwatch.StartNew() 
     For i = 0 To 50000 
      myExecute_Async(sqlstr) 
     Next 

    End Sub 

    Function myExecute_Async(ByVal sqlstr As String) As String 
      Using cmd As New SqlCommand(sqlstr, cnTest) 
       cmd.CommandType = CommandType.Text 
       cmd.BeginExecuteReader(New AsyncCallback(AddressOf QueryCallback), cmd) 
       Return "" 
      End Using 
    End Function 

    Sub QueryCallback(ByVal async As IAsyncResult) 
     ' ToDo: something 
    End Sub 

End Class 



CREATE TABLE [dbo].[test1](
    [ID] [int] IDENTITY(1,1) NOT NULL, 
    [name] [varchar](50) NULL, 
    [surname] [varchar](50) NULL, 
    [a2] [int] NULL, 
CONSTRAINT [PK_test1] PRIMARY KEY CLUSTERED 
(
    [ID] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 
GO 

статья «Класс .NET SqlConnection, пул соединений и переподключение логика» это не ответ. моя проблема заключается в асинхронном выполнении.

Я попытался использовать этот код. Я старался не использовать солнечные процедуры:

Dim cnstr As String = System.Configuration.ConfigurationManager.ConnectionStrings("ConnectionStringLOG").ConnectionString 
cnTest = New SqlConnection(cnstr) 
cnTest.Open() 

watch = Stopwatch.StartNew() 

For i = 0 To 50000 
    Using cmd As New SqlCommand(sqlstr, cnTest) 
     ' Return "" & cmd.ExecuteNonQuery() 
     cmd.CommandType = CommandType.Text 
     cmd.BeginExecuteReader(New AsyncCallback(AddressOf QueryCallback), cmd) 
    End Using 
Next 

на этот раз я получил исключение типа «System.OutOfMemoryException» был выброшен. в строке cmd.BeginExecuteReader.

позволяет сказать, что у меня есть логика, которая должна запускать эти 50 000 команд. что я должен делать, чтобы избежать проблем с памятью или ограничить лимит?

+0

Вот что я пробовал в первую очередь. но в конце myExecute_Async, когда вы закрываете соединение (или выходите за пределы использования), соединение исчезает из памяти, а функция обратного вызова не вызывается. очень странно, но вы также не получили сообщений об ошибках. функция обратного вызова просто не попадает. – AykutCanturk

+0

извините, «класс .NET SqlConnection, логика объединения и повторного подключения» не является ответом. моя проблема заключается в асинхронном выполнении. спасибо в любом случае. – AykutCanturk

+0

Вы все еще используете одно и то же соединение ... –

ответ

1

Для тех, кто пытается работать с большой нагрузкой сделки или заинтересованы в теме:

Лучший выбор будет замедленное воспламенение. Я также экспериментировал с потоками, но я понял, что этот фальшивый режим намного проще, и вам не нужно беспокоиться о перезапуске веб-пула, все может остановить службы IIS, такие как ошибки ...

Я назвал класс, который вставляет 10.000 записей на сервер sql, и я назвал его in..next со 100 раз. конечно, это заняло много времени, но это сработало как шарм. Также я убил процессы IIS, а затем все остановилось. когда я начал ИИС снова, все продолжалось оттуда.

Мне нравится это решение гораздо больше.

спасибо.

0

После многих испытаний я узнал, это: (может быть, у меня нет достаточно знаний) выполнение

асинхронной SQL запрос трудно. вы не можете легко ловить ошибки, если вы уничтожаете объекты соединения, вы не можете активировать функцию обратного вызова async.

очевидно, что он не предназначен для одновременного выполнения 50 000 запросов. Если вы думаете, что это не произойдет в реальной жизни, я не возражаю против этого.

вместо этого я использовал простое решение:

HostingEnvironment.QueueBackgroundWorkItem(Function(token) myTestClass.myExecute_Async(sqlstr, token)) 

50.000 запросов в течение ... Следующее утверждение и время выполнения было ZERO секунд. конечно, они поставлены в очередь, я заглядывал в таблицу sql и каждый раз, когда я запускал SELECT COUNT (1) FROM test1, я увеличивал показатель записи почти на 1 минуту. он вставил счетчик записей exactlu 50.001 (я смотрел на-дальше с нуля), и я чувствовал, что он работает более солидно. по крайней мере, я понимаю, что происходит за кулисами. Использование памяти IIS прошло до 114.000k и обратно обратно до 19.000k.

Я надеюсь, что это поможет кому-то еще в какой-то момент.

благодарит моих друзей.

+0

Лучшим решением было бы не выпускать все операторы 50k одновременно, но обрабатывать их по N потокам, где N подвергается экспериментированию (вероятно, рядом с количеством ядер). – usr

+0

Да, QueueBackgroundWorkItem делает это. Я знаю, что 50 000 запросов высоки, но мне нужно знать, что делает фреймворк под этой загрузкой. – AykutCanturk

+0

Все остальные работы в том же процессе будут заглушены. Остальная часть сайта остановится. Это нехорошее решение. – usr