简体   繁体   中英

Program logic to Update and Get data to/from same stored procedure

I am working on this project to create a Windows service that creates thread every 20 seconds. This service get text and numbers from stored procedure and sends SMS to those number, and at every end of thread it returns result to stored procedure.

In that logic, I have to call the stored procedure multiple times, so what I want to do is I want to get and update data at same time. The code flow is like this: this is the function that is called onStart of service.

public void Prepare(object state)
{
    DataTable _dt = new DataTable();
    DataTable _dt_sms_result = new DataTable();

    _dt = GetInfo();

    if (_dt != null)
    {
        _dt_sms_result.Columns.Add("sms_id", typeof(int));
        _dt_sms_result.Columns.Add("send_time", typeof(DateTime));
        _dt_sms_result.Columns.Add("result", typeof(string));

        foreach (DataRow dr in _dt.Rows)
        {
            bool status = sendMsg(dr["smsid"].ToString(), dr["number"].ToString(), dr["messagetxt"].ToString(), dr["from"].ToString(), dr["to"].ToString());
            Thread.Sleep(1000);
            DataRow lvlrow = _dt_sms_result.NewRow();
            lvlrow["sms_id"] = dr["sms_id"];
            lvlrow["send_time"] = DateTime.Now;

            if (status)
                lvlrow["result"] = "Message Sent";
            else
                lvlrow["result"] = "Sending Failed";

            _dt_sms_result.Rows.Add(lvlrow);
        }//end foreach
        PushInfo(_dt_sms_result);
    }

Code for GetInfo() :

public DataTable GetInfo()
{
    cmd.CommandText = "StoreProc_511";
    cmd.CommandType = CommandType.StoredProcedure;

    cmd.Parameters.Clear();

    cmd.Parameters.AddWithValue("@username", "******");            
    cmd.Parameters.AddWithValue("@authcode", "******");

    DataTable dt = new DataTable();

    try
    {
        Connect();
        SqlDataAdapter da = new SqlDataAdapter(cmd);
        da.Fill(dt);              
    }
    catch (SqlException se)
    {
        MyLog.Write(new LogPacket(se, DateTime.Now));
        return null;
    }
    finally
    {
        Disconnect();
    }
    return dt;        
}

Code for PushInfo() :

public void PushInfo(DataTable dt_sms_result)
{
    int res = -1;
    cmd.CommandText = "StoreProc_511";
    cmd.CommandType = CommandType.StoredProcedure;

    cmd.Parameters.Clear();
    cmd.Parameters.AddWithValue("@username", "*****");            
    cmd.Parameters.AddWithValue("@authcode", "*****");

    SqlParameter tvpParam = cmd.Parameters.AddWithValue("@sms_result", dt_sms_result);
    tvpParam.SqlDbType = SqlDbType.Structured;

    try
    {
        Connect();
        res = cmd.ExecuteNonQuery();
    }
    catch (SqlException se)
    {
        MyLog.Write(new LogPacket(se, DateTime.Now));            
        Disconnect();           
    }
    finally
    {
        Disconnect();
    }
}

What I have thought so far is to pass _dt_sms_result to GetInfo() and delete PushInfo() as we'll be making only one call. And add

SqlParameter tvpParam = cmd.Parameters.AddWithValue("@sms_result", dt_sms_result);
tvpParam.SqlDbType = SqlDbType.Structured;

to GetInfo() .

But I am still confused with the logic where that GetInfo(with DT) should be placed on Prepare() method.

Can some one help me with the logic here? Thanks!

Basically what I did to solve that problem is that, I declared datatable( _dt_sms_result ) as a class property and it is static, now each thread will update to one datatable( _dt_sms_result ) locally, so when a new thread is created after 20 secs and calls GetInfo() it also sends _dt_sms_result to stored procedure as a paramter. This call will get numbers, text and other info at same time and saves to datatable. To handle losing of data and deadlock during this call, I have locked this datatable until new datatable is retured by stored procedure.

Changed code of GetInfo() :

public DataTable GetInfo()
{
    DataTable dt = new DataTable();

    cmd.CommandText = "StoreProc_511";
    cmd.CommandType = CommandType.StoredProcedure;

    cmd.Parameters.Clear();
    cmd.Parameters.AddWithValue("@username", "*****");            
    cmd.Parameters.AddWithValue("@authcode", "*****");

    lock (_dt_sms_result) { 
        SqlParameter tvpParam = cmd.Parameters.AddWithValue("@dt_sms_res", _dt_sms_result);
        tvpParam.SqlDbType = SqlDbType.Structured;


        try
        {
            Connect();
            SqlDataAdapter da = new SqlDataAdapter(cmd);
            da.Fill(dt);
            _dt_sms_result.Rows.Clear();

        }
        catch (SqlException se)
        {
            MyLog.Write(new LogPacket(se, DateTime.Now));                
        }
        finally
        {
            Disconnect();
        }
    }
    return dt;

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM