Почему Oledb Connection.Close () занимает слишком много времени для выполнения? - PullRequest
0 голосов
/ 26 апреля 2019

Во время разработки настольного приложения для подключения к локальной базе данных я перемещал базу данных в сетевое расположение, и теперь каждый раз, когда я вызываю Connection.Close (), программа зависает на 5-15 секунд.Я видел эту проблему очень редко, когда база данных хранилась на локальном компьютере, но теперь, когда она находится в сети, она зависает почти каждый раз, когда я пытаюсь закрыть ().При первом обращении к базе данных я даже не запрашиваю ее, это просто тестовое соединение, которое я открываю и закрываю, чтобы убедиться, что пользователь может подключиться, но оно все еще висит слишком долго.

I 'Мы уже видели этот вопрос, заданный ранее, но никто не может предложить решение или решение, которое можно исправить, кроме как «попробуйте использовать () {}, чтобы c # очистил его».Это никак не влияет на время Close ().

Есть ли опция в строке подключения для решения этой проблемы?Кто-нибудь знает, почему это происходит?

Строка подключения, которую я использую:

CONNECTION_STRING = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=\\NEWTORK\Shared\Database\Database.accdb; Persist Security Info=False;"

private void

  Form_Login_Load(object sender, EventArgs e)
  {
    OleDbConnection Connection = new OleDbConnection();
    Connection.ConnectionString = CONNECTION_STRING;
    try
    {
      Console.Write("Connection Opening.....");
      Connection.Open();
      Console.WriteLine("Connection Opened");
      Console.Write("Writing Status Text.....");
      lbl_Status.Text = "Online";
      Console.WriteLine("Written Status Text");
      Console.Write("Connection Closing.....");
      Connection.Close();
      Console.WriteLine("Connection Closed");
    }
    catch (Exception Ex)
    {
      lbl_Status.Text = "Offline";
      lbl_Status.ForeColor = System.Drawing.Color.FromArgb(255, 0, 0);
      MessageBox.Show("Could not connect to Database");
    }
  }

В моем окне вывода я сразу вижу входящие сообщения и сообщения о состоянии записи, ноприложение зависает непосредственно перед 'Console.Write ("Закрытие соединения .....");линия.Через 5-15 секунд в окне появляется сообщение о закрытии.

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

Ответы [ 3 ]

1 голос
/ 30 апреля 2019

Что в итоге сработало для меня: Когда я получал длительное время задержки для метода Connection.Close (), я использовал ядро ​​базы данных Microsoft Access 2016 (x64). По несвязанной причине мне нужно было удалить движок 2016 года и перейти на версию 2010 (x86). Теперь мои времена Connection.Close () в среднем составляют ~ 40 мс, что вполне приемлемо для моего приложения.

0 голосов
/ 27 апреля 2019

Часто это могут быть настройки сервера.Если брандмауэр + защитник Windows активен, то он проверяет весь доступ к «файлу» - открывается очень медленно, и, конечно, close ().

Попробуйте запустить компьютер, на котором находится общая папка, с брандмауэром иЗащитник окон выключен.Я видел, что это часто исправляет большие задержки.Конечно, использование технологии на основе сокетов позволило бы устранить эту проблему (например, на основе сервера).Однако у вас есть то, что у вас есть, и часто причиной этого замедления является не скорость вашего кода, а система «файлов Windows», а также сетевое и антивирусное программное обеспечение.

0 голосов
/ 26 апреля 2019

Если между базой данных и программой имеются незавершенные транзакции, Close() откатит их.Он также должен запросить и удалить его из пула соединений, что может занять больше времени на удаленном диске.Может ли это быть вашей проблемой?

Вот документы по методу.

Чтобы решить эту проблему, вы можете использовать BackgroundWorker для его выполнения, например так:

var b = new BackgroundWorker();
b.DoWork += CloseDB;
b.RunWorkerCompleted += someMethodAfterClose;
b.RunWorkerAsync();

ЗакрытьDB:

public void CloseDB(object sender, DoWorkEventArgs e) {
    someConnection.Close();
}
...