Read Datatable and do a loop in rows async c# - c#

I'm trying to implement asynchronous methods in my program, and I want to read each row asynchronously from a datatable.
I have the following situation:
private void VerifyPermissions()
{
try
{
string constring = String.Format("server={0}; user id={1}; password={2}; database={3}; pooling=false", AcessoBancoDados.server, AcessoBancoDados.user, AcessoBancoDados.password, AcessoBancoDados.database);
MySqlConnection con = new MySqlConnection();
con.ConnectionString = constring;
con.Open();
var query = "SELECT id FROM users";
MySqlCommand cmd = new MySqlCommand(query, con);
MySqlDataAdapter da = new MySqlDataAdapter(query, con);
DataTable dt = new DataTable();
da.Fill(dt);
con.Close();
foreach (DataRow item in dt.Rows)
{
Messagebox.Show(item["id"].ToString());
}
}
And the call method:
private void button1_Click(object sender, EventArgs e)
{
VerifyPermissions()
}
Anyone can show me an async situation for this? Thanks.

according to your comment you would need something like my code below.
If you use SqlCommand instead of SqlDataAdapter you will have async methods already and don't need to create a task.
(also don't mix ui and data access. keep them separate.)
private async void button1_Click(object sender, EventArgs e)
{
await VerificarPermissoes();
}
private async Task VerificarPermissoes()
{
await Task.Run(() =>
{
// put your code from above here.
});
}

Well, you can do this basically by creating tasks in c#, see the example below
private void VerificarPermissoes()
{
try
{
DataTable dt = new DataTable();
string constring = String.Format("");
string query = "SELECT id FROM users";
using (SqlConnection con = new SqlConnection(constring))
{
con.Open();
DbCommand command = con.CreateCommand();
command.CommandText = query;
dt.Load(command.ExecuteReader());
}
foreach (DataRow item in dt.Rows)
{
Task.Factory.StartNew(delegate () { ProcessItem(item["id"].ToString()); });
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void ProcessItem(string item)
{
AddControl(myControl, childControl);
}
private void button1_Click(object sender, EventArgs e)
{
VerificarPermissoes();
}
private void AddControl(Control ctrl, Control child)
{
if (ctrl.InvokeRequired)
{
Action act = delegate () { AddControl(ctrl, child); };
this.Invoke(act);
}
else
{
ctrl.Controls.Add(child);
}
}

Related

the process can not access the file 'bin\debug' because it is being used by another process

this is my code
i have tried every step i can find
i have moved con.close(); before and after it is still not working
please guide me to what to do
thank you
I am following this youtube video to make the crud operation https://www.youtube.com/watch?v=C7ukAjQtsxE
using System.Data;
using System.Data.SqlClient;
namespace crudingtime
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
SqlConnection con = new SqlConnection("Data Source=DESKTOP-6381H14\\SQLEXPRESS;Initial Catalog=yarabthis;Integrated Security=True");
private void Form1_Load(object sender, EventArgs e)
{
GetEmpList();
}
private void imtired_Click(object sender, EventArgs e)
{
con.Open();
int id = int.Parse(idbox.Text);
string fname=fnametxt.Text, lname=lnametxt.Text;
SqlCommand c = new SqlCommand("exec ughh'"+id+"','"+fname+"','"+lname+"','",con);
con.Close();
MessageBox.Show("Successfully inserted");
}
void GetEmpList()
{
SqlCommand c = new SqlCommand("exec Listughh", con);
SqlDataAdapter sd=new SqlDataAdapter(c);
DataTable dt = new DataTable();
sd.Fill(dt);
dataGridView1.DataSource = dt;
}
}
}```
don't try and persist the connection at the form class level - since then you can't control when you dispose of it.
So, try say like this, and always have a using code block (which will clean up all your connections for you).
And it not clear why you have a public form method here, so let's just leave that issue out of the picture for the time being.
and I assume that a hard coded connection string was JUST for this post, not that you are using hard coded connection strings all over the place - (don't do that!!!).
And you tagged this as asp.net so we assuem this is a web page, right?
Thus, this "air code" should suffice:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
GetEmpList();
}
private void imtired_Click(object sender, EventArgs e)
{
int id = int.Parse(idbox.Text);
SqlCommand c = new SqlCommand("ughh");
c.Parameters.Add("#ID", SqlDbType.Int).Value = id;
c.Parameters.Add("#fname", SqlDbType.NVarChar).Value = fnametxt.Text;
c.Parameters.Add("#lname", SqlDbType.NVarChar).Value = lnametxt.Text;
MyRstP(c, false);
MessageBox.Show("Successfully inserted");
}
void GetEmpList()
{
SqlCommand c = new SqlCommand("Listughh");
DataTable dt = new DataTable();
DataGridView1.DataSource = MyRstP(c);
DataGridView1.DataBind();
}
public DataTable MyRstP(SqlCommand cmdSQL, bool returnData = true)
{
DataTable rstData = new DataTable();
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (cmdSQL)
{
cmdSQL.Connection = conn;
conn.Open();
cmdSQL.CommandType = CommandType.StoredProcedure;
if (returnData)
{
rstData.Load(cmdSQL.ExecuteReader());
}
else
{
cmdSQL.ExecuteNonQuery();
}
}
}
return rstData;
}
And as for that file in use.
Reboot your computer.
So, "isolate" your connection routine(s). Don't attempt to persist the connection at the form/class level, move your connection string to config or settings. (and bonus points is you can use the connection builder).

WPF - How to clear items before repopulating combobox

I am trying to make cascading combo boxes. When I select values in combo boxes for the first time everything is OK, but when I return to first combo box and change to some other value, new items in the other combos are appended to the old items. This is my code bellow:
public Apartment()
{
InitializeComponent();
}
SqlConnection con = new SqlConnection(Connection.cnnDatabase1);
Database1DataSet ds = new Database1DataSet();
private void FillLocation()
{
//locationCombo.Items.Clear()
SqlDataAdapter daLocation= new SqlDataAdapter("select * from Location", con);
daLocation.Fill(ds, "Location");
con.Open();
locationCombo.ItemsSource = ds.Tables["Location"].DefaultView;
locationCombo.DisplayMemberPath = "Location";
locationCombo.SelectedValuePath = "IdLocation";
con.Close();
}
private void FillCity(String IdLocation)
{
/*cityCombo.Items.Clear() -- I have tried inserting this,
but I am getting an error "Operation is not valid while ItemsSource is in use.
Access and modify elements with ItemsControl.ItemsSource instead." on that part
when I reselect the combo.*/
SqlDataAdapter daCity= new SqlDataAdapter("select * from City where IdLocation= " + IdLocation, con);
daCity.Fill(ds, "City");
con.Open();
cityCombo.ItemsSource = ds.Tables["City"].DefaultView;
cityCombo.DisplayMemberPath = "City";
cityCombo.SelectedValuePath = "IdCity";
con.Close();
}
private void FillStreet(String IdCity)
{
//cityCombo.Items.Clear()
SqlDataAdapter daStreet= new SqlDataAdapter("select * from Street where IdCity= " + IdCity, con);
daStreet.Fill(ds, "Street");
con.Open();
cityCombo.ItemsSource = ds.Tables["Street"].DefaultView;
cityCombo.DisplayMemberPath = "Street";
cityCombo.SelectedValuePath = "IdStreet";
con.Close();
}
private void Window_Loaded_1(object sender, RoutedEventArgs e)
{
FillLocation();
}
private void locationCombo_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
String idLocation= locationCombo.SelectedValue.ToString();
FillCity(idLocation);
}
private void cityCombo_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
String idCity = cityCombo.SelectedValue.ToString();
FillStreet(idCity);
}
Try this:
public Apartment()
{
InitializeComponent();
}
SqlConnection con = new SqlConnection(Connection.cnnDatabase1);
Database1DataSet ds = new Database1DataSet();
private void FillLocation()
{
//locationCombo.Items.Clear()
SqlDataAdapter daLocation= new SqlDataAdapter("select * from Location", con);
ds.Tables["Location"].Clear();
daLocation.Fill(ds, "Location");
con.Open();
locationCombo.ItemsSource = ds.Tables["Location"].DefaultView;
locationCombo.DisplayMemberPath = "Location";
locationCombo.SelectedValuePath = "IdLocation";
con.Close();
}
private void FillCity(String IdLocation)
{
/*cityCombo.Items.Clear() -- I have tried inserting this,
but I am getting an error "Operation is not valid while ItemsSource is in use.
Access and modify elements with ItemsControl.ItemsSource instead." on that part
when I reselect the combo.*/
if(!String.IsNullOrWhiteSpace(IdLocation))
{
ds.Tables["City"].Clear();
SqlDataAdapter daCity= new SqlDataAdapter("select * from City where IdLocation= " + IdLocation, con);
daCity.Fill(ds, "City");
con.Open();
cityCombo.ItemsSource = ds.Tables["City"].DefaultView;
cityCombo.DisplayMemberPath = "City";
cityCombo.SelectedValuePath = "IdCity";
con.Close();
}
}
private void FillStreet(String IdCity)
{
if(!String.IsNullOrWhiteSpace(IdCity))
{
s.Tables["Street"].Clear();
SqlDataAdapter daStreet= new SqlDataAdapter("select * from Street where IdCity= " + IdCity, con);
daStreet.Fill(ds, "Street");
con.Open();
cityCombo.ItemsSource = ds.Tables["Street"].DefaultView;
cityCombo.DisplayMemberPath = "Street";
cityCombo.SelectedValuePath = "IdStreet";
con.Close();
}
}
private void Window_Loaded_1(object sender, RoutedEventArgs e)
{
FillLocation();
}
private void locationCombo_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if(locationCombo.SelectedValue != null)
{
String idLocation= locationCombo.SelectedValue.ToString();
FillCity(idLocation);
}
}
private void cityCombo_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if(cityCombo.SelectedValue != null)
{
String idCity = cityCombo.SelectedValue.ToString();
FillStreet(idCity);
}
}
Since cityCombo.Items.Clear() is not an option in this case as mentioned in the code comments, you can clear the datatable instead:
ds.Tables["City"].Clear();
And in order to avoid the NullReferenceException in cityCombo_SelectionChanged you can check the cityCombo.SelectedValue for null.
You are reusing the DataSet everywhere. So it will keep appending. As I said in the comments, either clear the DataSet or make a local one to each function.

Update SQL query, unsure why it isn't working as no errors are appearing

I have been staring at this UPDATE statement for a long while and are unsure why my table isn't changing. When I press the button no error appears but my table doesn't not get updated either, I have checked that all of my variables have values on debug and they do.
I'd appreciate any help anyone can give me!
This is the code that contains the statement I need help with:
private void button1_Click(object sender, EventArgs e)
{
string studentanswertext = textBox1.Text;
string connectionString = ConfigurationManager.ConnectionStrings["myconnectionstring"].ConnectionString;
string y = GlobalVariableClass.Signedinteacher;
Convert.ToInt32(y);
MessageBox.Show(y);
MessageBox.Show(Convert.ToString(CurrentQuestionID));
MessageBox.Show(studentanswertext);
SqlConnection connect = new SqlConnection(connectionString);
connect.Open();
SqlCommand command20 = new SqlCommand(#"UPDATE QuestionStudentAssociation SET ([StudentAnswer]=#StudentAnswertext) WHERE ([QuestionID]=#CurrentQID AND [StudentID]=#SignedinStudent )", connect);
command20.Parameters.AddWithValue("#StudentAnswertext", studentanswertext);
command20.Parameters.AddWithValue("#CurrentQID", CurrentQuestionID);
command20.Parameters.AddWithValue("#SignedinStudent", y);
command20.BeginExecuteNonQuery();
connect.Close();
}
This is the whole code for my form if anyone wanted to look at it just in case that is affecting the button even handler:
namespace ComputingA2_Official_Project
{
public partial class CurrentlySetTestForm : Form
{
Timer loopTimer = new Timer();
private int CurrentQuestionID { get; set; }
private string QuestionSpace { get; set; }
public CurrentlySetTestForm()
{
InitializeComponent();
}
private void CurrentlySetTestForm_Load(object sender, EventArgs e)
{
string y = GlobalVariableClass.Signedinteacher;
Convert.ToInt32(y);
string connectionString = ConfigurationManager.ConnectionStrings["myconnectionstring"].ConnectionString;
SqlConnection connect = new SqlConnection(connectionString);
connect.Open();
SqlCommand command18 = new SqlCommand("SELECT MIN([QuestionID]) AS QuestionID FROM QuestionStudentAssociation WHERE ( [StudentID]=#Signedinstudent AND [StudentAnswer] IS NULL )", connect);
command18.Parameters.AddWithValue("#Signedinstudent", y);
var reader = command18.ExecuteReader();
while (reader.Read())
{
CurrentQuestionID = Convert.ToInt32(reader[0]);
SqlCommand command19 = new SqlCommand("SELECT ([Question Space]) FROM Questions WHERE ([QuestionID]=#CurrentQID)", connect);
command19.Parameters.AddWithValue("#CurrentQID", CurrentQuestionID);
using (SqlDataReader reader2 = command19.ExecuteReader())
{
while (reader2.Read())
{
QuestionSpace = Convert.ToString(reader2[0]);
label1.Text = QuestionSpace;
}
}
}
connect.Close();
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
string studentanswertext = textBox1.Text;
string connectionString = ConfigurationManager.ConnectionStrings["myconnectionstring"].ConnectionString;
string y = GlobalVariableClass.Signedinteacher;
Convert.ToInt32(y);
MessageBox.Show(y);
MessageBox.Show(Convert.ToString(CurrentQuestionID));
MessageBox.Show(studentanswertext);
SqlConnection connect = new SqlConnection(connectionString);
connect.Open();
SqlCommand command20 = new SqlCommand(#"UPDATE QuestionStudentAssociation SET ([StudentAnswer]=#StudentAnswertext) WHERE ([QuestionID]=#CurrentQID AND [StudentID]=#SignedinStudent )", connect);
command20.Parameters.AddWithValue("#StudentAnswertext", studentanswertext);
command20.Parameters.AddWithValue("#CurrentQID", CurrentQuestionID);
command20.Parameters.AddWithValue("#SignedinStudent", y);
command20.BeginExecuteNonQuery();
connect.Close();
}
private void timer1_Tick(object sender, EventArgs e)
{
}
}
}
I believe the issue is that you are executing the command asynchronously (BeginExecuteNonQuery), but never calling EndExecuteNonQuery to commit it. I also suspect you could just call it synchronously like this:
command20.ExecuteNonQuery();

Filtering combobox with another combobox value

I have three combo-box which filtering value in different tables. For the first two combo-box i have no problem but for the third combo-box, I got error show input strings was not in correct format. I using the same code for the other two and it working correctly. Can someone specify how to troubleshoot this problem?
Here my code:-
This one is for combobox two which worked perfectly:-
private void cbBridge_SelectedIndexChanged(object sender, EventArgs e)
{
if (cbBridge.SelectedValue.ToString() != null)
{
int BridgeID = Convert.ToInt32(cbBridge.SelectedValue.ToString());
FillPier(BridgeID);
}
}
This is the code which show error
private void cbPier_SelectedIndexChanged(object sender, EventArgs e)
{
if (cbPier.SelectedValue.ToString() != null)
{
int PierID = Convert.ToInt32(cbPier.SelectedValue.ToString());
FillDataPoint(PierID);
}
}
I hope someone can show me how to rectify this problem. Thanks.
***UPDATE****
Here the full code
private void FillPier(int BridgeID)
{
SqlConnection con = new SqlConnection(conString);
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT PierID, PierName, BridgeID FROM tbPier WHERE BridgeID = #BridgeID";
cmd.Parameters.AddWithValue("#BridgeID", BridgeID);
DataSet objDs = new DataSet();
SqlDataAdapter dAdapter = new SqlDataAdapter();
dAdapter.SelectCommand = cmd;
con.Open();
dAdapter.Fill(objDs);
con.Close();
if (objDs.Tables[0].Rows.Count > 0)
{
cbPier.DataSource = objDs.Tables[0];
cbPier.DisplayMember = "PierName";
cbPier.ValueMember = "PierID";
}
}
private void FillDataPoint(int PierDP)
{
SqlConnection con = new SqlConnection(conString);
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT PierID, InspectDate FROM tbDatapoint WHERE PierID = #PierID";
cmd.Parameters.AddWithValue("#PierID", PierDP);
DataSet objDs = new DataSet();
SqlDataAdapter dAdapter = new SqlDataAdapter();
dAdapter.SelectCommand = cmd;
con.Open();
dAdapter.Fill(objDs);
con.Close();
if (objDs.Tables[0].Rows.Count > 0)
{
cbInspect.DataSource = objDs.Tables[0];
cbInspect.DisplayMember = "InspectDate";
cbInspect.ValueMember = "PierID";
}
}
private void ViewBridge_Load(object sender, EventArgs e)
{
FillBridge();
}
private void cbBridge_SelectedIndexChanged(object sender, EventArgs e)
{
if (cbBridge.SelectedValue.ToString() != null)
{
int BridgeID = Convert.ToInt32(cbBridge.SelectedValue.ToString());
FillPier(BridgeID);
}
}
private void cbPier_SelectedIndexChanged(object sender, EventArgs e)
{
if (cbPier.SelectedIndex != 1)
{
int PierDP = Convert.ToInt32(cbPier.SelectedValue.ToString());
FillDataPoint(PierDP);
}
}
Check if this can be converted to int first like this:
int x = 0
private void cbPier_SelectedIndexChanged(object sender, EventArgs e)
{
if (Int32.TryParse(cbPier.SelectedValue.ToString(), out x))
{
int PierID = Convert.ToInt32(cbPier.SelectedValue.ToString());
FillDataPoint(PierID);
}
}
Or using the SelectedIndex property:
if(cbPier.SelectedIndex != -1)
{
.....
}
What are the cbPier.DisplayMember and cbPier.ValueMember ? Is the diplay member the string and value member the int? Double check if that's the case first ...

StackOverflowException unhandled on SqlDataAdapter.Fill()

StackOverflowException was unhandled. I need help on this. I get the error on the line
adp.Fill(ds)
Also I'm not sure why, but I can't remove throw, it says not all codes returning a value.
string connStr = System.Configuration.ConfigurationManager.ConnectionStrings["dbCustConn"].ToString();
string cmdStr = "Select * from MainDB";
public DAL() // default parameter. Use?
{
}
public DataTable Load() // what is this for? (loads all the records from the database)
{
SqlConnection conn = new SqlConnection(connStr);
//SqlCommand cmd = new SqlCommand(cmdStr, connStr);
SqlDataAdapter adp = new SqlDataAdapter(cmdStr, connStr); // SqlDataAdapater? Load all?
DataSet ds = new DataSet();
try
{
adp.Fill(ds);
return ds.Tables[0];
}
catch
{
throw;
}
finally
{
ds.Dispose();
adp.Dispose();
conn.Close();
conn.Dispose();
}
}
public DataTable Load() // what is this for? (loads all the records from the database)
{
SqlDataAdapter adp = new SqlDataAdapter(cmdStr, connStr); // SqlDataAdapater? Load all?
DataSet ds = new DataSet();
using(SqlConnection conn = new SqlConnection(connStr))
{
adp.Fill(ds);
return ds.Tables[0];
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindGrid();
}
}
private void BindGrid()
{
MasterCust.DataSource = GridDataSource();
MasterCust.DataBind();
//DetailCust.DataSource = ds2;
//DetailCust.DataBind();
}
private DataTable GridDataSource()
{
BAL p = new BAL();
DataTable dTable = new DataTable();
try
{
dTable = p.Load();
}
catch (StackOverflowException ee)
{
string message = ee.Message.ToString();
}
finally
{
p = null;
}
return dTable;
}
First, I think the issue is probably in MasterCust. I think that however that is defined may be causing your issues. If you update your question on how this is defined, that may shed some additional light.
Second, you have a lot of extraneous code that could be confusing the issue. Here is what I think that you need to do to pare it down the bare minimum:
protected void Page_Load(object sender, EventArgs e)
{
try
{
if (!IsPostBack)
{
BindGrid();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
// Note that this is for debug purposes only. Production code should log
// this exception somewhere so that it can be observed and dealt with
}
}
private void BindGrid()
{
MasterCust.DataSource = BAL.Load();
MasterCust.DataBind();
}
Then your business access class:
public class BAL
{
private static string connStr = System.Configuration.ConfigurationManager.ConnectionStrings["dbCustConn"].ToString();
private static string cmdStr = "Select * from MainDB";
public static DataTable Load() // what is this for? (loads all the records from the database)
{
using (var adp = new SqlDataAdapter(cmdStr, connStr))
{
var ds = new DataSet();
adp.Fill(ds);
return ds.Tables[0];
}
}
}

Categories