New to c#. I have a winform with a combobox, button and progress bar. On the button click event text is taken from the textbox and used in a sql query. While this query is running, I would like a progress bar (marquee - does not need to show % complete) to animate, when the query is complete I would like it to stop.
I have tried the below code but get the error:
'Cross-thread operation not valid: Control 'cbTest' accessed from a thread other than the thread it was created on.'.
private System.Windows.Forms.ProgressBar _progressBar;
public Test()
{
InitializeComponent();
_progressBar = progressBar;
}
private void Form1_Load_1(object sender, EventArgs e)
{
_progressBar.Style = ProgressBarStyle.Marquee;
_progressBar.MarqueeAnimationSpeed = 0;
}
public async void btn_Click(object sender, EventArgs e)
{
await Task.Run(() => GetValues(_progressBar));
}
private void GetValues(System.Windows.Forms.ProgressBar progressBar)
{
progressBar.Invoke(new System.Action(() =>
{
progressBar.MarqueeAnimationSpeed = 30;
}));
Sql.SqlQuery("exec Test..sp_Test " + cbTest.Text);
progressBar.Invoke(new System.Action(() =>
{
progressBar.Style = ProgressBarStyle.Blocks;
progressBar.Style = ProgressBarStyle.Marquee;
progressBar.MarqueeAnimationSpeed = 0;
}));
}
public static void SqlQuery(string queryString, string connectionString = "Data Source= Test; Initial Catalog = Test; Integrated Security = True")
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand command = new SqlCommand(queryString, connection);
command.CommandTimeout = 300;
command.Connection.Open();
command.ExecuteNonQuery();
}
}
This has got absolutely zero to do with the ProgressBar
. Raed the error message. It says that you are accessing cbTest
- the ComboBox
- on the wrong thread. You obviously know that you have to access the ProgressBar
on the UI thread. Why do you think it's OK to do otherwise for the ComboBox
?
The solution would be to not access the ComboBox
in that methopd at all. Change that method to accept a string
as well and then get the Text
from the ComboBox
before creating the Task
and pass that string
in.
To be honest, I would do nothing but the query in that method. Do all the pre-query UI stuff first, then create the Task
to perform the query, passing in any data that is required. After the
Task` completes, do the post-query UI stuff.