wp8的任务队列?

在wp8中对复杂任务进行排队的正确方法是什么?

任务包括以下内容:

  1. 通过更新模型变量显示ProgressIndicator
  2. 获取或存储数据到wcf服务( UploadStringAsync
  3. 使用UploadStringCompleted的结果更新潜在的数据绑定模型。
  4. 通过更新模型变量隐藏ProgressIndicator

目前我一直在使用一个拥有命令对象队列的类,运行一个在添加项目时启动的线程(如果它尚未运行)。

但是,我有等待代码停止运行的任务或子任务的问题。

以前我曾经使用异步等待,但是行为的几个级别变得越来越难以预测。

我想要的是能够创建和排队命令对象的主线程。 命令对象应该一次运行一个,而不是在前一个完全完成之前启动一个新对象。 如果需要,命令对象应该能够使用调度程序访问主线程。

如果使用async / await ,则不需要另一个线程(因为您没有CPU绑定处理)。

在您的情况下,听起来您只需要一个异步委托队列。 异步委托的自然类型是Func (没有返回值)或Func> (带有返回值)。 遗憾的是,这个小小的提示在这一点上并不为人所知。

因此,声明一个异步委托队列:

 private readonly Queue> queue = new Queue>(); 

然后,您可以只有(异步)处理队列的单个“顶级”任务:

 private Task queueProcessor; 

只要没有更多项, queueProcessor就可以为null 。 每当它不为null ,它将代表这种方法:

 private async Task ProcessQueue() { try { while (queue.Count != 0) { Func command = queue.Dequeue(); try { await command(); } catch (Exception ex) { // Exceptions from your queued tasks will end up here. throw; } } } finally { queueProcessor = null; } } 

您的Enqueue方法将如下所示:

 private void Enqueue(Func command) { queue.Enqueue(command); if (queueProcessor == null) queueProcessor = ProcessQueue(); } 

现在,我有这样的exception处理设置:抛出exception的任何排队命令将导致队列处理器停止处理(具有相同的exception)。 这可能不是您的应用程序的最佳行为。

您可以像这样使用它(当然,使用lambda或实际方法):

 Enqueue(async () => { ShowProgressIndicator = true; ModelData = await myProxy.DownloadStringTaskAsync(); ShowProgressIndicator = false; }); 

注意使用DownloadStringTaskAsync 。 如果您为EAP成员编写TAP包装器 ,您的async代码将更“自然”(即,更简单)。

这非常复杂,我建议将它放入一个单独的类中,但是你想要先决定如何处理(和表面)错误。