0

我有一个生成事件的用户界面。所以我有一个事件,例如带有参数的“ButtonPressed”。在事件中,我想触发耗时的函数“GenerateTableData”。另外我不想阻塞接口,所以这个函数应该在后台线程上。在此之后,我可以将调用传递回主线程并填充列。
但是,如果用户在 Button 上按下两次,我不想创建两个线程。相反,我想打断前一个或等到它完成并立即启动另一个(单独的按钮用单独的数据填充表格,我们只需要显示最后一次按下的结果)。

我被这个选项卡住了。在我看来,所有的工作都是在每个事件上投射 backgroundworker,但我不能阻止它执行两次或更多次,也不能将进一步的事件排队。

请给我一个解决此任务的示例,我认为它应该很常见。

这是一些伪代码:

void Button1Pressed(args)
{
DoWork(1);
}
void Button2Pressed(args)
{
DoWork(2);
}

void DoWork(int i)
{
BackGroundWorker bg=new BackGroundWorker();
bg.DoWork+= (object sender, DoWorkEventArgs e) => {e.result=GenerateTable(i)};
bg.RunWorkerCompleted+= (object sender, RunWorkerCompletedEventArgs e) =>{InvokeOnMainThread(()=>{PopulateColumns(e.result)})};
bg.RunWorkerAsync();
}
void PopulateColumns(data)
{
myTable.PopulateWithData(data);
}
4

1 回答 1

0

执行此操作的典型方法是:

  • 对于每个应该序列化的事件类型,都有一个队列
  • 引发事件是将事件排队并踢队列(见下文)
  • 用一种方法包裹你的工人,在完成任务后
    • 重置“工人正在运行”标志(不需要锁定)
    • 再次插队

通过“踢队列”我的意思是

  • 检查“worker is running”标志,如果设置了,什么都不做(结束的worker会重新踢)
  • 尝试从锁定队列中出列,如果它是空的,解锁并且什么都不做
  • 所以我们有工作要做:解锁队列之前,设置“worker is running”标志
于 2013-06-26T20:54:10.857 回答