Как запустить SqlDataReader и SqlDataAdapter одновременно? - PullRequest
1 голос
/ 02 июля 2019

Как исправить код, чтобы исключение больше не появлялось?

SqlConnection
    sqlCnn = new SqlConnection("Connection String");

SqlCommand
    sqlCmdSelect = new SqlCommand("SQL SELECT statement;", sqlCnn),
    sqlCmdUpdate = new SqlCommand("SQL UPDATE statement;", sqlCnn);

Thread
    t1 = new Thread(()=>{
        SqlDataReader sdr;
        while(true)
        {
            sdr = sqlCmdSelect.ExecuteReader();
            // Do some works
            sdr.Close();
        }
    }),
    t2 = new Thread(()=>{
        SqlDataAdapter sda;
        while(true)
        {
            using(sda = new SqlDataAdapter())
            {
                // Do some works
                sda.UpdateCommand = sqlCmdUpdate;
                if(!sdr.IsClosed) sdr.Close();
                sda.UpdateCommand.ExecuteNonQuery();
            }
        }
    });

t1.Start();
t2.Start();

System.InvalidOperationException: «Уже есть открытый DataReader, связанный с этой командой, который должен быть закрыт первым.»

Ответы [ 2 ]

0 голосов
/ 02 июля 2019

На самом деле вы можете выполнять несколько операций на одном соединении, используя MARS :

Несколько активных наборов результатов (MARS) - это функция, которая работает с SQL Server и позволяет выполнятьиз нескольких партий на одном соединении.Когда MARS включен для использования с SQL Server, каждый используемый объект команды добавляет сеанс к соединению.

, чтобы включить его, просто измените строку подключения, добавив к ней MultipleActiveResultSets=True следующим образом:

Data Source=MSSQL1;Initial Catalog=AdventureWorks;Integrated Security=SSPI;MultipleActiveResultSets=True

Никаких других изменений кода не требуется, но помните, что это изменение конфигурации, поэтому, если у вас есть настроенные среды, такие как test, staging, вам нужно распространить это изменение и на эти среды.

0 голосов
/ 02 июля 2019

Как говорит исключение, вы не можете выполнить две операции с одним и тем же соединением.

Я бы просто создал два объекта класса SqlConnection и использовал бы их отдельно в потоках.

В качестве альтернативы, вы можете использовать некоторую синхронизацию при выполнении операторов SQL (lock, Semaphore), но это будет полностью противоположно тому, что вы хотите сделать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...