In a WPF application I have an SQL query that takes some times to execute and I want to implement a BackgroundWorker with a progress bar so that the user can see when it's finished.
Here's the XAML part :
<Grid Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<ProgressBar x:Name="BgProgBar" Margin="5"/>
<TextBlock x:Name="Perc_TB" HorizontalAlignment="Center"
VerticalAlignment="Center"
Text="{Binding Path=Value,ElementName=BgProgBar}"/>
</Grid>
and here's my BackgroundWorker in code behind :
public partial class Supp_Stocks : Page
{
private string _user = Settings.Default.User;
private DataTable dt;
SqlConnection conn;
SqlCommand comm;
SqlConnectionStringBuilder connStringBuilder;
BackgroundWorker Bg = new BackgroundWorker();
public Supp_Stocks()
{
InitializeComponent();
ConnectToDB();
Bg.DoWork += Bg_DoWork;
Bg.ProgressChanged += Bg_ProgressChanged;
Bg.WorkerReportsProgress = true;
}
#region BackGroundWorker
private void Bg_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
BgProgBar.Value = e.ProgressPercentage;
}
private void Bg_DoWork(object sender, DoWorkEventArgs e)
{
for(int i = 0; i < 100; i++)
{
try
{
comm = new SqlCommand("select STOCK_ENT.ENT_ID,ENT_DATE_ENT,ENT_NUMPAL,CLI_NOM,ART_LIBELLE1,ENT_PICKING,SUM(det_pnet)" +
" as POIDS_NET from STOCK_DET, STOCK_ENT, CLIENTS, FICHES_ARTICLES, MVTS_SEQUENCE where SEQ_STATUT <> 'V' and" +
" STOCK_ENT.ENT_ID = STOCK_DET.ENT_ID and STOCK_ENT.ENT_PROP = CLI_CODE and STOCK_ENT.ART_CODE = FICHES_ARTICLES.ART_CODE" +
" and STOCK_ENT.ENT_ID = MVTS_SEQUENCE.ENT_ID group by STOCK_ENT.ENT_ID, ENT_DATE_ENT, ENT_NUMPAL, CLI_NOM, ART_LIBELLE1, ENT_PICKING order by ART_LIBELLE1", conn);
SqlDataAdapter dap = new SqlDataAdapter(comm);
dt = new DataTable();
dap.Fill(dt);
Stocks_DT.ItemsSource = dt.DefaultView;
Bg.ReportProgress(i);
}
catch (Exception ex)
{
var stList = ex.StackTrace.ToString().Split('\\');
Messages.ErrorMessages($"ERREUR : \n{ex.Message}\n\nException at : \n{stList[stList.Count() - 1]}");
}
}
}
private void GenerateStk_Btn_Click(object sender, RoutedEventArgs e)
{
Bg.RunWorkerAsync();
}
#endregion
private void ConnectToDB()
{
connStringBuilder = new SqlConnectionStringBuilder
{
DataSource = @"VM-VISUALSTORE\SQLEXPRESS,1433",
InitialCatalog = "GSUITE",
Encrypt = true,
TrustServerCertificate = true,
ConnectTimeout = 30,
AsynchronousProcessing = true,
MultipleActiveResultSets = true,
IntegratedSecurity = true,
};
conn = new SqlConnection(connStringBuilder.ToString());
comm = conn.CreateCommand();
}
}
but when executing the code its returns an error:
Sorry it's in French but it says that "The thread cannot access this object because another thread owns it.