Фоновый поток, выполняющий доступ к БД, зависает - PullRequest
0 голосов
/ 03 февраля 2011

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

Чтобы пользовательский интерфейс реагировал быстро и видел шаги прогресса, я помещаю код БДв фоновом потоке.К моему изумлению, пользовательский интерфейс все еще зависает (но не так сильно).

В этом приложении нет ничего особенного, но я подумал, что в общем случае интересно, что код БД в потоке зависаетПользовательский интерфейс!

    private void bgwDataAccess_DoWork(object sender, DoWorkEventArgs e)
    {
        BackgroundWorker bgw = sender as BackgroundWorker;

        try
        {
            bgw.ReportProgress(0, "Starting...\r\n");
            bgw.ReportProgress(0, "Active ConnectionString:\r\n");
            bgw.ReportProgress(0, Settings.Default.ConnctionString + "\r\n\r\n");

            OracleConnection con = new OracleConnection(Settings.Default.ConnctionString);
            OracleCommand cmd = new OracleCommand("SELECT Count(*) FROM MYTABLE", con);


            bgw.ReportProgress(0, "Opening db...\r\n");
            con.Open();
            bgw.ReportProgress(0, "Opened.\r\n\r\n");

            bgw.ReportProgress(0, "Executing SQL-query...\r\n");
            Object result = cmd.ExecuteScalar();
            bgw.ReportProgress(0, String.Format("Result: {0}\r\n\r\n", result.ToString()));

            con.Close();
        }
        catch (Exception)
        {
            throw;
        }
    }

    private void bgwDataAccess_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        txtResult.Text += e.UserState;           
    }

Ответы [ 2 ]

1 голос
/ 03 февраля 2011

Есть ли у вас доступ к пространству имен Oracle где-либо в вашем коде до этого?Это всего лишь предположение, но, возможно, эта пауза приводит к тому, что ваше приложение загружает требуемые .dlls

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

void PreloadDLLs()
{
    Assembly^ assembly = Assembly::GetEntryAssembly();
    array<System::Reflection::AssemblyName^>^ referencedAssemblies = assembly->GetReferencedAssemblies();
    for each(System::Reflection::AssemblyName^ referencedAssemblyName in referencedAssemblies)
    {
        try
        {
            Assembly^ a = assembly->Load(referencedAssemblyName);
        }
        catch(System::Exception^ /*e*/)
        {

        }
    }
}

Извинения за синтаксис C ++ / CLI, но, надеюсь, вы сможете увидеть, как преобразовать его в C # - мой немного ржавый: -)

[Редактировать] Я думаю, что это в значительной степени C #:

using System;
using System.Reflection;

private void PreloadDLLs()
{
    Assembly assembly = Assembly.GetEntryAssembly();
    System.Reflection.AssemblyName[] referencedAssemblies = assembly.GetReferencedAssemblies();
    foreach(System.Reflection.AssemblyName referencedAssemblyName in referencedAssemblies)
    {
        try
        {
            Assembly a = assembly.Load(referencedAssemblyName);
        }
        catch
        {

        }
    }
}
0 голосов
/ 03 февраля 2011

Вы можете изменить запрос на «ВЫБЕРИТЕ верхний 1 идентификатор из MYTABLE», и результат будет таким же.

Если воздействие не вызвано этими операциями, вы можете использовать профилировщик, чтобы выяснить, какой код .net вызывает воздействие.

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