在c#中线程化Oracle查询

时间:2014-07-08 14:24:47

标签: c# multithreading oracle

我理解线程的概念,但我一般都是新手,所以请耐心等待。如果这是一个无趣的问题,请道歉。

我需要在Windows窗体程序中对Oracle数据库运行一些密集查询。虽然此代码可以正常工作,但程序会冻结,因为查询可能需要一分钟才能运行,而且我按顺序运行了几个。我认为创建一个单独的线程,如下所示,可以防止这种情况发生。我是否需要在创建线程时指定一些内容,表明只有一定数量的资源应该专用于它?我在Google上找到了一些答案,但并没有真正了解它们。

提前感谢您的帮助!

    private void loginButton_Click(object sender, EventArgs e)
    {
        loginStatus.Text = "STATUS: Running...";
        Thread thread1 = new Thread(new ThreadStart(GetLoginData));            
        thread1.Start();
        loginStatus.Text = "STATUS: Ready";
    }

    private void GetLoginData()
    {
        try
        {

            Invoke(new Action(() => loginButton.Enabled = false));

            string LDS01_start = "select count(*) from BBLEARN.AUTH_PROVIDER_LOG where AUTH_PROVIDER_PK1 = 103 ";
            string LDAPS_start = "select count(*) from BBLEARN.AUTH_PROVIDER_LOG where AUTH_PROVIDER_PK1 = 106 ";
            string middle = "and log_date >= '" + GetDate(loginStartDate) + @"' 
                         and log_date < '" + GetDate(loginEndDate) + @"' ";

            string LDS01_0 = LDS01_start + middle + "and event_type = 0";
            string LDS01_1 = LDS01_start + middle + "and event_type = 1";
            string LDS01_2 = LDS01_start + middle + "and event_type = 2";
            string LDS01_5 = LDS01_start + middle + "and event_type = 5";
            string LDS01_6 = LDS01_start + middle + "and event_type = 6";

            string LDAPS_0 = LDAPS_start + middle + "and event_type = 0";
            string LDAPS_1 = LDAPS_start + middle + "and event_type = 1";
            string LDAPS_2 = LDAPS_start + middle + "and event_type = 2";
            string LDAPS_5 = LDAPS_start + middle + "and event_type = 5";
            string LDAPS_6 = LDAPS_start + middle + "and event_type = 6";

            Invoke(new Action(() => GetData(LDS01_0, LDS01_LB0)));
            Invoke(new Action(() => GetData(LDS01_1, LDS01_LB1)));
            Invoke(new Action(() => GetData(LDS01_2, LDS01_LB2)));
            Invoke(new Action(() => GetData(LDS01_5, LDS01_LB5)));
            Invoke(new Action(() => GetData(LDS01_6, LDS01_LB6)));

            Invoke(new Action(() => GetData(LDAPS_0, LDAPS_LB0)));
            Invoke(new Action(() => GetData(LDAPS_1, LDAPS_LB1)));
            Invoke(new Action(() => GetData(LDAPS_2, LDAPS_LB2)));
            Invoke(new Action(() => GetData(LDAPS_5, LDAPS_LB5)));
            Invoke(new Action(() => GetData(LDAPS_6, LDAPS_LB6)));

            Invoke(new Action(() => loginButton.Enabled = true));
            loginStatus.Text = "STATUS: Ready";

        }
        catch (Exception e)
        {
            Debug.WriteLine(e);
        }
    }

    private void GetData(string selectCommand, Label label)
    {
        //open the connection
        OracleConnection conn = new OracleConnection(connectString);
        conn.Open();

        //define the command
        selectCommand = selectCommand.Replace(Environment.NewLine, " ");
        OracleDataAdapter dataAdapter = new OracleDataAdapter(selectCommand, conn);
        OracleCommandBuilder commandBuilder = new OracleCommandBuilder(dataAdapter);

        //run the command
        DataTable table = new DataTable();
        table.Locale = System.Globalization.CultureInfo.InvariantCulture;
        dataAdapter.Fill(table);

        //pull the result
        label.Text = table.Rows[0][0].ToString();

        //close the connection
        conn.Close();

    }

1 个答案:

答案 0 :(得分:2)

你是invoking GetData()方法,调用使用UI线程,GetData()方法是针对数据库的,并且花费时间让你的屏幕锁定。你需要简单地调用UI更改然后线程关闭数据库调用,完成后调用UI线程启用按钮等...

GetLoginData()更改您的来电:

Invoke(new Action(() => GetData(LDS01_0, LDS01_LB0)));

对此:

GetData(LDS01_0, LDS01_LB0);

将GetData()更改为:

private void GetData(string selectCommand, Label label)
{
    //open the connection
    OracleConnection conn = new OracleConnection(connectString);
    conn.Open();

    //define the command
    selectCommand = selectCommand.Replace(Environment.NewLine, " ");
    OracleDataAdapter dataAdapter = new OracleDataAdapter(selectCommand, conn);
    OracleCommandBuilder commandBuilder = new OracleCommandBuilder(dataAdapter);

    //run the command
    DataTable table = new DataTable();
    table.Locale = System.Globalization.CultureInfo.InvariantCulture;
    dataAdapter.Fill(table);
    //close the connection
    conn.Close();

    Invoke(new Action(() => RenderData(label, table.Rows[0][0].ToString())));


}

创建这个新的RenderData()方法:

private void RenderData(Label label, string text)
{
    label.Text = text;
}