Исключение с уже открытым DataReader при использовании задачи <int>для чтения из MySql - PullRequest
0 голосов
/ 09 мая 2020

У меня есть этот код в методе:

Task<int> linksCount = Task<int>.Factory.StartNew(() => { return DatabaseIn.GetUrlsCount(); });
Task<int> imagesCount = Task<int>.Factory.StartNew(() => { return DatabaseIn.GetImagesCount(); });

Позже отображаются linksCount и imagesCount.Result. Однако когда я запускаю этот код в первый раз. Я получаю следующее исключение:

Уже существует открытый DataReader, связанный с этим подключением, которое необходимо сначала закрыть.

Код, в котором создается исключение:

MySqlCommand comm = null;
string cmdString = "SELECT COUNT(*) FROM damocles.imagestoassess;";

comm = new MySqlCommand(cmdString, conn);

if (comm.ExecuteScalar() == null)
{
    comm.Dispose();
    conn.Close();
    return 0;
}

int res = Convert.ToInt32(comm.ExecuteScalar());

comm.Dispose();
conn.Close();
return res;

Исключение возникает при первом вызове ExecuteScalar. Если я заключу код в предложение try..catch, код продолжится, но в другой части кода возникнет другая ошибка.

Вопрос:

  1. Почему это вызывает исключение? При синхронном запуске не возникает никаких исключений.
  2. Как исправить, чтобы код работал асинхронно?

Спасибо.

1 Ответ

1 голос
/ 09 мая 2020

A MySqlConnection может использоваться только одним потоком одновременно. Ваше исключение происходит из-за того, что оба Task используют один и тот же объект conn. Для получения дополнительной информации см. https://mysqlconnector.net/troubleshooting/connection-reuse/.

Ваш код будет работать, если вы создадите и используете new MySqlConnection внутри каждого Task.

Вдобавок это давняя ошибка , что асинхронные c операции в MySql. Данные фактически не являются асинхронными. Вам нужно будет переключиться на MySqlConnector , чтобы получить асинхронный ввод-вывод для MySQL операций.

...