Reputation: 195
i have created a form1 with button1 to start a task, which will be processed on the background with BackGroundWorker on a separate class and display a ProgressBar on a separate window.
my problem is the process is working fine except that the task is done yet progressbar form hangs on the middle.
below is BackGroundLoading Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.ComponentModel;
namespace sample2
{
public class BackgroundLoading
{
public BackgroundWorker Bw;
public delegate void RunFunction();
public RunFunction thisFunction;
mycontrols.LoadProgress p = new mycontrols.LoadProgress();
public BackgroundLoading(RunFunction newFunction)
{
thisFunction = newFunction;
Bw = new BackgroundWorker();
Bw.WorkerReportsProgress = true;
Bw.DoWork += new DoWorkEventHandler(Bw_DoWork);
Bw.ProgressChanged += new ProgressChangedEventHandler(Bw_ProgressChanged);
Bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(Bw_RunWorkerCompleted);
}
public void Start()
{
Bw.RunWorkerAsync();
}
void Bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
{
MessageBox.Show("Error: " + e.Error.Message);
}
if (e.Cancelled)
{
MessageBox.Show("Cancelled!");
}
else
{
MessageBox.Show("Completed!");
p.Close();
}
}
public void Bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
/// If I put
/// p.ProgBar.Value = e.ProgressPercentage;
/// the progressbar hangs upon form show.
}
void Bw_DoWork(object sender, DoWorkEventArgs e)
{
p.Show();
BackgroundWorker worker = sender as BackgroundWorker;
for (int i = 1; (i <= 100); i++)
{
if ((worker.CancellationPending == true))
{
e.Cancel = true;
break;
}
else
{
if (thisFunction != null)
{
thisFunction();
worker.ReportProgress((i * 1));
p.ProgBar.Value = i;
}
else
{
MessageBox.Show("Error, no method found");
}
}
}
}
}
}
this is the Form1 code.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace sample2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
BackgroundLoading BL = new BackgroundLoading(workingmethod);
BL.Start();
}
private void workingmethod()
{
System.Threading.Thread.Sleep(10);
}
}
}
this is the code for the LoadProgress form
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace sample2.mycontrols
{
public partial class LoadProgress : Form
{
public LoadProgress()
{
InitializeComponent();
}
private void LoadProgress_Load(object sender, EventArgs e)
{
}
}
}
no code on the progressbar form since update is done on the class. can't find the causing of hanging.
Thanks in Advance.
Upvotes: 1
Views: 1108
Reputation: 66511
Show the form on the main UI thread, immediately prior to running your BackgroundWorker
:
public void Start()
{
p.Show();
Bw.RunWorkerAsync();
}
Then you can make calls to the form in the ProgressChanged
event, which runs on the UI thread.
Remove p.Show()
and p.ProgBar.Value = i;
from the DoWork
event - you don't want to touch the UI thread from your background thread.
public void Bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
p.ProgBar.Value = e.ProgressPercentage;
}
Finally, close the form when the BackgroundWorker
is complete (which you're already doing):
void Bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
p.Close();
}
Upvotes: 1