8

Как мой предыдущий вопрос: How to stay connected to database until screen close?Должно ли объединение пулов быть намного медленнее, чем поддерживать соединение открытым?

Во-первых, Позвольте мне извиниться за вас, что я не объясняю свою ситуацию.

Ну, моя ситуация обновляется до ста записей. Я создаю реальную работу с For loop и записываю их результат.

private void button1_Click(object sender, EventArgs e) 
{ 
    int i; 
    KeyEventArgs keyEvent = new KeyEventArgs(Keys.Enter); //Create keydown event 

    Performance perf = new Performance(); //Class for measure time and logging 

    perf.Start(); //Start stopwatch 

    for (i = 1; i <= 100; i++) 
    { 
     txtLotNo.Text = i.ToString("0000000000") + "$01"; //Generate input ID 

     txtLotNo_KeyDown(sender, keyEvent); //Fire keydown event 
    } 

    perf.Stop(); //Stop stopwatch 

    perf.Log(frmInvCtrl.appPath,"Stock In (Stay connected)- " + frmInvCtrl.instance); //Logging 
} 

Это класс производительности.

class Performance 
{ 
    private Stopwatch _sw = new Stopwatch(); //Create stopwatch property 

    public double GetWatch 
    { 
     get 
     { 
      return this._sw.ElapsedMilliseconds; 
     } 
    } 

    public void Start() 
    { 
     Stop(); 

     _sw.Reset(); 
     _sw.Start(); 
    } 

    public void Stop() 
    { 
     if (_sw.IsRunning) 
     { 
      _sw.Stop(); 
     } 
    } 

    public void Log(string path,string menu) 
    { 
     string logName = path + "\\Log_" + System.DateTime.Now.ToString("yyyyMMdd") + ".txt"; 
     string logDetail = System.DateTime.Now.ToString("yyyy/MM/dd hh:mm:ss") + " - [" + menu + "] " 
      + "Process 100 record in [" + (((double)_sw.ElapsedMilliseconds/1000)).ToString() + "] seconds"; 

     using(StreamWriter writer = new StreamWriter(logName,true)) 
     { 
      writer.WriteLine(logDetail); //wirtelog 
     } 
    } 
} 

И это результат журнала

2017/02/19 08:16:05 - [Stock In - On Cloud] Process 100 record in [68.352] seconds 
2017/02/19 08:17:34 - [Stock In - On Cloud] Process 100 record in [70.184] seconds 
2017/02/19 08:20:28 - [Stock In - On Cloud] Process 100 record in [56.66] seconds 
2017/02/19 08:21:34 - [Stock In - On Cloud] Process 100 record in [60.605] seconds 
2017/02/19 08:22:44 - [Stock In - On Cloud] Process 100 record in [68.27] seconds 
2017/02/19 08:24:43 - [Stock In - Network Server] Process 100 record in [46.86] seconds 
2017/02/19 08:26:05 - [Stock In - Network Server] Process 100 record in [31.746] seconds 
2017/02/19 08:26:48 - [Stock In - Network Server] Process 100 record in [31.859] seconds 
2017/02/19 08:27:32 - [Stock In - Network Server] Process 100 record in [31.003] seconds 
2017/02/19 08:28:17 - [Stock In - Network Server] Process 100 record in [40.487] seconds 
2017/02/19 08:32:42 - [Stock In (Stay connected)- On Cloud] Process 100 record in [18.196] seconds 
2017/02/19 08:35:47 - [Stock In (Stay connected)- On Cloud] Process 100 record in [14.721] seconds 
2017/02/19 08:36:30 - [Stock In (Stay connected)- On Cloud] Process 100 record in [15.903] seconds 
2017/02/19 08:37:31 - [Stock In (Stay connected)- On Cloud] Process 100 record in [15.811] seconds 
2017/02/19 08:38:15 - [Stock In (Stay connected)- On Cloud] Process 100 record in [16.4] seconds 
2017/02/19 08:43:08 - [Stock In (Stay connected)- Network Server] Process 100 record in [13.09] seconds 
2017/02/19 08:43:25 - [Stock In (Stay connected)- Network Server] Process 100 record in [13.03] seconds 
2017/02/19 08:43:40 - [Stock In (Stay connected)- Network Server] Process 100 record in [13.051] seconds 
2017/02/19 08:43:55 - [Stock In (Stay connected)- Network Server] Process 100 record in [12.992] seconds 
2017/02/19 08:44:12 - [Stock In (Stay connected)- Network Server] Process 100 record in [14.953] seconds 

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

Есть ли какая-либо практика, подходящая для этого случая?

EDIT: 2017/02/21

Вот открытое соединение, когда открытая форма код:

private void frm_Load(object sender, EventArgs e) //Open menu 
{ 
    ... //statement 

    frmMain.sqlConn1 = new SqlConnection(); 
    frmMain.sqlConn1.ConnectionString = frmMain.connectionString1; 
    frmMain.sqlConn1.Open(); 

    ... //statement 
} 

Обновить код:

public static long ScanUpdate(string lotNo) 
{ 
    string scanLotNo = ""; 
    int scanIndex = 0; 

    if (!SplitBarcode(lotNo, ref scanLotNo, ref scanIndex)) 
    { 
     //Invalid Barcode data 
     return -919; 
    } 

    //Prepare sql command 
    string updStatus = (frmMain.shelfScan) ? "05" : "10"; 
    string sql = <sql statement> 

    try 
    { 
     using (SqlCommand sqlCmd = new SqlCommand(sql, frmMain.sqlConn1)) //frmMain.sqlConn1 is connection in form_Load() 
     { 
      if (sqlCmd.ExecuteNonQuery() <= 0) 
      { 
       //No row affect 
       //frmMain.sndPlay.Play(); 
       return -99; 
      } 
      else 
      { 
       //Completed 
       return 0; 
      } 
     } 
    } 
    catch 
    { 
     return 99; 
    } 
    finally 
    { 

    } 
} 

И отчуждать соединение при выходе

private void btnBack_Click(object sender, EventArgs e) 
{ 
    frmMain.sqlConn1.Dispose(); 
    this.Close(); 
} 
+2

Вы уверены, что вызываете 'Close()' в соединении, поэтому соединение возвращается в пул? Вы оценили время, когда вы не используете пул и открываете _new_ соединение для каждого обновления? –

+0

В тесте (Оставайтесь на связи) я открыл соединение на 'Form_Load()' при открытии меню и Dispose при закрытой форме. Пока я открываю меню, я могу обновлять записи, используя это соединение, пока открыто меню. И без (оставаться на связи) я использую 'using' block и не вызываю' Close() 'после блока, как мой предыдущий вопрос. –

+0

@ MitchWheat. Вы имеете в виду, что мне нужно закрыть соединение, когда закончите обновление 100 записей, вместо этого закройте соединение каждой записи за 100 раз? –

ответ

2

Часть, которую здесь не хватает, заключается в том, что ее Windows CE, ее не редкость. Открывающиеся соединения на компактной версии могут быть очень медленными.

Это сказало, однако, эти времена выглядят немного преувеличенными. См. Этот QA для обходных путей: How can I make my SQL Server CE connection open faster?

4

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

Каждый раз, когда соединение выдается в пул соединений и затем используется повторно, стек протокола выполняет вызов sp_resetconnection для очистки состояния на сервере. Это можно увидеть, запустив трассировку профилировщика для SQL Server.

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

0

Существует ряд областей, где вы можете столкнуться с проблемами с кодом выше.

  • Вы создаете экземпляр SqlConnection.
  • Все обработчики событий вызывают статическую функцию, которая ссылается на один экземпляр SqlConnection.
  • Обработчики событий не проверяют, запущены ли они в основном потоке пользовательского интерфейса.

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

Адрес reference to some connection string properties. Взгляните на Connection Lifetime.

Я хотел бы удалить экземпляр SqlConnection из функции form_load() и писать ScanUpdate следующим образом:

public static long ScanUpdate(string lotNo) 
{ 
    string scanLotNo = ""; 
    int scanIndex = 0; 

    if (!SplitBarcode(lotNo, ref scanLotNo, ref scanIndex)) 
    { 
     //Invalid Barcode data 
     return -919; 
    } 

    //Prepare sql command 
    string updStatus = (frmMain.shelfScan) ? "05" : "10"; 
    string sql = <sql statement> 

    try 
    { 
     using (SqlConnection conn = new SqlConection(frmMain.connectionString1)) { 
      SqlCommand sqlCmd = new SqlCommand(sql, conn); 
      if (sqlCmd.ExecuteNonQuery() <= 0) 
      { 
       //No row affect 
       //frmMain.sndPlay.Play(); 
       return -99; 
      } 
      else 
      { 
       //Completed 
       return 0; 
      } 
      conn.Close(); 
     }    
    } 
    catch 
    { 
     return 99; 
    } 
} 

Для ваших *_Click функций обработчика событий, убедитесь, чтобы проверить, чтобы проверить, нужно ли повторно вызывается событие:

private void button1_Click(object sender, EventArgs e) 
{ 
    if (this.InvokeRequired) 
    { 
     this.Invoke(new EventArgsDelegate(button1_Click), new object[] { sender, ea }); 
    } 

    // Do some stuff 
} 

См. this answer для получения дополнительной информации об обработке событий.

Смежные вопросы