Car*_*l R 0 c# task dispatcher windows-phone-7 windows-phone-8
在wp8中对复杂任务进行排队的正确方法是什么?
任务包括以下内容:
ProgressIndicator通过更新模型变量UploadStringAsync)UploadStringCompleted.ProgressIndicator更新模型变量目前我一直在使用一个拥有命令对象队列的类,运行一个在添加项目时启动的线程(如果它尚未运行).
但是,我有等待代码停止运行的任务或子任务的问题.
以前我曾经使用异步等待,但是行为的几个级别变得越来越难以预测.
我想要的是能够创建和排队命令对象的主线程.命令对象应该一次运行一个,而不是在前一个完全完成之前启动一个新对象.如果需要,命令对象应该能够使用调度程序访问主线程.
如果你使用async/ await,则不需要另一个线程(因为你没有CPU绑定处理).
在您的情况下,听起来您只需要一个异步委托队列.异步委托的自然类型是Func<Task>(没有返回值)或Func<Task<T>>(带有返回值).遗憾的是,这个小小的提示在这一点上并不为人所知.
因此,声明一个异步委托队列:
private readonly Queue<Func<Task>> queue = new Queue<Func<Task>>();
Run Code Online (Sandbox Code Playgroud)
然后,您可以只有(异步)处理队列的单个"顶级"任务:
private Task queueProcessor;
Run Code Online (Sandbox Code Playgroud)
只要没有更多的物品,queueProcessor就可以null.每当它不是null,它将代表这种方法:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
您的Enqueue方法将如下所示:
private void Enqueue(Func<Task> command)
{
queue.Enqueue(command);
if (queueProcessor == null)
queueProcessor = ProcessQueue();
}
Run Code Online (Sandbox Code Playgroud)
现在,我有这样的异常处理设置:抛出异常的任何排队命令将导致队列处理器停止处理(具有相同的异常).这可能不是您的应用程序的最佳行为.
您可以像这样使用它(当然,使用lambda或实际方法):
Enqueue(async () =>
{
ShowProgressIndicator = true;
ModelData = await myProxy.DownloadStringTaskAsync();
ShowProgressIndicator = false;
});
Run Code Online (Sandbox Code Playgroud)
注意使用DownloadStringTaskAsync.如果您为EAP成员编写TAP包装器,您的async代码将更"自然"(即更简单).
这非常复杂,我建议将它放到一个单独的类中,但是你想要先决定如何处理(和表面)错误.
| 归档时间: |
|
| 查看次数: |
910 次 |
| 最近记录: |