wp8的工作queue列? [英] Task queue for wp8?

查看:78
本文介绍了wp8的工作queue列?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

What is a correct way to queue complex tasks in wp8?

任务包括以下内容:


  1. 通过更新模型变量显示 ProgressIndicator

  2. 获取数据或将数据存储到wcf服务中( UploadStringAsync

  3. 使用 UploadStringCompleted 的结果更新潜在的数据绑定模型。

  4. 通过更新模型变量来隐藏 ProgressIndicator

  1. Showing a ProgressIndicator through updating a model variable
  2. Fetching or storing data to a wcf service (UploadStringAsync)
  3. Updating potentially data bound model with the result from UploadStringCompleted.
  4. Hiding the ProgressIndicator through updating a model variable

当前,我正在与拥有命令对象队列的类一起工作,运行一个线程,该线程在添加项(如果尚未运行)时启动。

Currently I've been working with a class owning a queue of command objects, running a single thread that is started when an item is added if it's not already running.

但是我在等待代码停止运行的任务或子任务时遇到问题。

I have however problems with waiting for tasks or subtasks where the code stops running.

以前我使用过async await,但是在行为上有几层变得越来越不可预测。

Previously I've used async await, but a few levels down the behaviour was becoming more and more unpredictable.

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

What I want is the main thread being able to create and queue command objects. The command objects should run one at a time, not starting a new one until the previous one is completely finished. The command objects should be able to use the dispatcher to access the main thread if neccesary.

推荐答案

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

If you use async/await, there's no need for another thread (since you have no CPU-bound processing).

在您的情况下,听起来您只需要一个异步委托队列。异步委托的自然类型是 Func< Task> (无返回值)或 Func< Task< T>> (带有返回值)。不幸的是,这个小技巧目前还不为人所知。

In your case, it sounds like you just need a queue of asynchronous delegates. The natural type of an asynchronous delegate is Func<Task> (without a return value) or Func<Task<T>> (with a return value). This little tip is unfortunately not well-known at this point.

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

So, declare a queue of asynchronous delegates:

private readonly Queue<Func<Task>> queue = new Queue<Func<Task>>();

然后,您可以拥有一个仅(异步)处理队列的顶级任务:

Then you can have a single "top-level" task that just (asynchronously) processes the queue:

private Task queueProcessor;

queueProcessor 可以为 null 每当没有其他项目时。每当它不是 null 时,它将代表此方法:

The queueProcessor can be null whenever there's no more items. Whenever it's not null, it'll represent this method:

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

您的入队方法将如下所示:

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

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

Right now, I have the exception handling set up like this: any queued command that throws an exception will cause the queue processor to stop processing (with the same exception). This may not be the best behavior for your application.

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

You can use it like this (with either a lambda or an actual method, of course):

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

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

Note the use of DownloadStringTaskAsync. If you write TAP wrappers for your EAP members, your async code will be more "natural-looking" (i.e., simpler).

这太复杂了,我想建议将其放在单独的类中,但您首先要决定如何处理(和显示)错误。

This is sufficiently complex that I'd recommend putting it into a separate class, but you'd want to decide how to handle (and surface) errors first.

这篇关于wp8的工作queue列?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆