BackgroundWorker bw;
private ManualResetEvent manualReset = new ManualResetEvent(true); private void button3_Click(object sender, EventArgs e)
{
using ( bw = new BackgroundWorker())
{
bw.WorkerReportsProgress = true;
bw.WorkerSupportsCancellation = true;
bw.ProgressChanged += bw_ProgressChanged;
bw.RunWorkerCompleted += bw_RunWorkerCompleted;
bw.DoWork += bw_DoWork; //允许用户指定显示数据的范围呢!所以需要把100作为参数传递给计算过程
bw.RunWorkerAsync();
} }
//这时返回了主线程,所以可以直接使用UI控件了
void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
//修改进度条的显示。
//this.progressBarSum.Value = e.ProgressPercentage; //如果有更多的信息需要传递,可以使用 e.UserState 传递一个自定义的类型。
//这是一个 object 类型的对象,您可以通过它传递任何类型。
//我们仅把当前 sum 的值通过 e.UserState 传回,并通过显示在窗口上。
string message = e.UserState.ToString();
label1.Text = message;
}
//e.Argument=bw.RunWorkerAsync("Hello World")的参数
void bw_DoWork(object sender, DoWorkEventArgs e)
{
System.Diagnostics.Debug.WriteLine("bw_DoWork"); BackgroundWorker bgWorker = sender as BackgroundWorker; //这里的操作是在另一个线程上完成的,不应该操作UI
//在这里执行耗时的运算。 int endNumber = ;
if (e.Argument != null)
{
endNumber = (int)e.Argument;
} for (int i = ; i <= endNumber; i++)
{
manualReset.WaitOne();
//如果ManualResetEvent的初始化为终止状态(true),那么该方法将一直工作,
//直到收到Reset信号。然后,直到收到Set信号,就继续工作。 bgWorker.ReportProgress(i, "current num:" + i.ToString());
Thread.Sleep(); //为了方便演示
if (bgWorker.CancellationPending)
{
e.Cancel = true;
System.Diagnostics.Debug.WriteLine("CancellationPending");
break;
} } }
//停止
private void button4_Click(object sender, EventArgs e)
{
bw.CancelAsync();
}
//暂停/继续
private void button5_Click(object sender, EventArgs e)
{
if (btnPause.Text == "暂停")
{
manualReset.Reset();//暂停当前线程的工作,发信号给waitOne方法,阻塞
btnPause.Text = "继续";
}
else
{
manualReset.Set();//继续某个线程的工作
btnPause.Text = "暂停";
}
}

请注意红色字体, 采用信号量 ManualResetEvent来控制暂停/继续

ManualResetEvent 允许线程通过发信号互相通信。通常,此通信涉及一个线程在其他线程进行之前必须完成的任务。当一个线程开始一个活动(此活动必须完成后,其他线程才能开始)时,它调用 Reset 以将 ManualResetEvent 置于非终止状态,此线程可被视为控制 ManualResetEvent。调用 ManualResetEvent 上的 WaitOne 的线程将阻止,并等待信号。当控制线程完成活动时,它调用 Set 以发出等待线程可以继续进行的信号。并释放所有等待线程。一旦它被终止,ManualResetEvent 将保持终止状态(即对 WaitOne 的调用的线程将立即返回,并不阻塞),直到它被手动重置。可以通过将布尔值传递给构造函数来控制 ManualResetEvent 的初始状态,如果初始状态处于终止状态,为 true;否则为 false。

最新文章

  1. 清除svn账户账号密码
  2. ZedGraph饼图---傻瓜版
  3. JS驗證兩位小數
  4. C#中Guid类型值如何判断不是初始值!
  5. JavaScript原型链和instanceof运算符的暧昧关系
  6. 进程同步(二)—— 信号量&amp;内存共享
  7. 获取sde 工作空间 propertys
  8. Configuring My Site in SharePoint 2010
  9. 导入 Mysql 示例数据库 employees
  10. 《Genesis-3D开源游戏引擎--横版格斗游戏制作教程02:关键帧动画导入与切割》
  11. Windows环境变量修改
  12. Yeslab现任明教教主数据中心第二门课程UCS 视频教程下载
  13. 依赖注入(DI)和控制反转(IOC)
  14. byte数组转16进制 输出到文件
  15. PHP7.X连接SQLSERVER数据库(CENTOS7)
  16. day6 note 字典的增删改查(以及setdefault用法补充)
  17. function(){}、var fun=function(){}和function fun(){}的区别
  18. cdnbest节点后台的3311如何登陆
  19. java之String类在堆栈存储机制
  20. git-fork其他人的代码

热门文章

  1. [PHP] PHP-FPM的access日志error日志和slow日志
  2. appium---元素定位方法
  3. centos下载安装libgcc 和 libtiff
  4. 编译 lineageos 14.1 on OnePlus3
  5. 关于join的使用
  6. tf.summary.scalar()和tf.summary.histogram
  7. Python进阶-XVI 继承 单继承 多继承
  8. Spring Cloud Alibaba Sentinel对RestTemplate的支持
  9. Ubuntu 16.04 + OpenCV 自定义环境变量 pkg-config / PKG_CONFIG_PATH
  10. golang基础之第一个go程序