простой многопоточный c # exe для проверки масштабируемости хранимых процедур SQL - PullRequest
0 голосов
/ 15 сентября 2011

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

Я пытаюсь отбросить БД, чтобы увидеть, какой будет критическая точка, создав простоймногопоточное приложение для вызова процедуры несколько раз и отображения временной метки результатов в виде сетки.Затем я просто прокручиваю сетку вниз, чтобы увидеть продолжительность от первого результата до последнего, чтобы определить, сколько результатов я могу обслуживать в секунду.

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

В двух словах, у меня есть таблица, такая как этот userId, newMsgCount с кластеризованным индексом на userId.SQL должен иметь возможность отправлять сотни таких ответов в секунду.Я думаю, что отстающим является мое приложение .NET.

Как я могу сделать этот тест хорошим для достижения результатов теста на основе производительности SQL?

У меня есть текстовое поле, которое занимает несколько БДвызовы и кнопка для вызова теста, затем сетка для отображения результатов.

private void btnSend_Click(object sender, EventArgs e)
{
    int count = Convert.ToInt32(txtThreadCount.Text);
    dtStatus = new DataTable();
    dtStatus.Columns.Add(new DataColumn("Thread No."));
    //dtStatus.Columns.Add("User Id");
    dtStatus.Columns.Add("Count");
    dtStatus.Columns.Add("time");

    for (int i = 0; i < count; i++)
    {
        ThreadPool.QueueUserWorkItem(GetMessageCount, i);
    }

    MessageBox.Show("Results retrieved successfully. \n Please see the result tab.");
    grdEmail.DataSource = dtStatus;
    grdEmail.Refresh();
}

private static void GetMessageCount(object threadContext)
{
    SqlCommand cmd = new SqlCommand();
    cmd.Connection = new SqlConnection();
    cmd.Connection.ConnectionString = "Data Source=server1;Initial Catalog=emails;Persist Security Info=True;User ID=IS_User;Password=M1";
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.CommandText = "sel_Message_New_Count";
    cmd.Parameters.AddWithValue("@UserId", 4);
    SqlDataAdapter da = new SqlDataAdapter();
    DataSet ds = new DataSet();
    da.SelectCommand = cmd;
    da.Fill(ds);

    if (ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
    {

        DataRow dr = dtStatus.NewRow();
        dr[0] = dtStatus.Rows.Count + 1;
        //dr[1] = 1;
        dr[1] = ds.Tables[0].Rows[0][0];
        dr[2] = DateTime.Now.ToString("hh:mm.ss:ffff");
        dtStatus.Rows.Add(dr);
    }
}

Ответы [ 2 ]

0 голосов
/ 15 сентября 2011
  • У вас массовые проблемы с утечкой памяти. Вам нужен оператор using для SQLCommand, SQLConnection, SQLDataAdapter.
  • Не используйте DataSet, используйте DataTable и утилизируйте его в операторе using.
  • Вы уверены, что DataTable.NewRow () является поточно-безопасной конструкцией, с помощью которой вы можете просто отбросить ее полной строк?
  • Почему вы выполняете этот код в событии нажатия кнопки? Событие нажатия кнопки должно порождать фоновый поток, который, в свою очередь, выполняет код, который у вас есть в событии нажатия кнопки. Затем пользовательский интерфейс должен отобразить строку состояния, указывающую процессы этого фонового потока ...

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

Вам нужно дождаться окончания каждого потока.

Как ты это делаешь? Вот одно из решений - или - вы можете попробовать использовать Parallel.For, если вы используете .NET 4 и параллельную библиотеку задач.

0 голосов
/ 15 сентября 2011

Вы можете попытаться изменить количество потоков, которые использует ThreadPool. См. Метод ThreadPool.SetMinThreads .

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