2013-06-26 34 views
0

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

我被这个选项卡住了。所有对我来说都很有用的工作是在每个事件上投入背景工作,但我无法阻止它执行两次或更多次,也无法排队进一步事件。

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

下面是一些伪代码:

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); 
} 

回答

0

做到这一点的典型方式是:

  • 为每个事件类型,应序列,有一个队列
  • 引发事件正排队事件和踢队列(见下文)
  • 将工人包装在一个方法中,在完成任务后
    • 重置了一个 “工人正在运行” 标志(无需锁定)
    • 踢队列再次

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

  • 检查“工人正在运行”标志,如果已设置,则什么也不做(结束工人将重新踢)
  • 尝试从锁定队列中退出,如果是空的,解锁,什么也不做
  • 所以我们有工作要做:以前解锁队列中,将“工人正在运行”国旗
+0

什么是更好的方式来组织队列?列表还是smth? –

+0

无论最合适 - 我通常使用System.Collections.Generic.Queue (http://msdn.microsoft.com/en-us/library/7977ey2c.aspx) –

+0

谢谢。一整天都在尝试创建解决方案,并一直努力重现错误。问题是在内部方法中读取SQLite不是线程安全的。最后,我明白了,现在没问题。 –