using System;
using System.Drawing;
using System.Windows.Forms;
using System.ComponentModel;
namespace AsyncWorkerCs {
public partial class uclBgwPrgbar : UserControl {
struct Data2Thread {
public DateTime Time;
public Point Pt;
}
struct Data2Gui {
public string Text;
public Point Pt;
}
public uclBgwPrgbar() {
InitializeComponent();
UpdateGui();
}
private void UpdateGui() {
btCancel.Visible = progressBar1.Visible = backgroundWorker1.IsBusy;
if(backgroundWorker1.IsBusy) {
this.MouseDown -= ucl_MouseDown;
progressBar1.Value = 0;
} else { this.MouseDown += ucl_MouseDown; }
}
void ucl_MouseDown(object sender, MouseEventArgs e) {
Data2Thread d = new Data2Thread() { Time = DateTime.Now, Pt = e.Location };
backgroundWorker1.RunWorkerAsync(d);
UpdateGui();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) {
//unpack arguments
Data2Thread d = (Data2Thread)e.Argument;
var p = d.Pt;
var t = d.Time;
//evaluate data
for(var i = 0; i < 300; i++) {
System.Threading.Thread.Sleep(10);
backgroundWorker1.ReportProgress(i / 3); //reports 300 "progresses"
if(backgroundWorker1.CancellationPending) {
e.Cancel = true;
return;
}
}
//pack results
Data2Gui d2g = new Data2Gui() {
Pt = p,
Text = string.Format("Position {0} / {1}\nclicked at {2:T}", p.X, p.Y, t)
};
e.Result = d2g;
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
UpdateGui();
if(e.Cancelled) {
label1.Text = "Canceled";
return;
}
Data2Gui d2g = (Data2Gui)e.Result; //unpack results
label1.Text = d2g.Text;
label1.Location = d2g.Pt - label1.Size;
}
private void btCancel_Click(object sender, EventArgs e) {
backgroundWorker1.CancelAsync();
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) {
progressBar1.Value = e.ProgressPercentage;
}
}
}