【发布时间】:2012-10-09 00:53:03
【问题描述】:
我需要一些有关 TPL 和任务的帮助
这是我的场景:
我有一些产生任务的事件处理程序。如果一个事件在其上一个任务完成之前被调用,我想在继续之前等待(阻止)它。
我有一个同步方法,在调用该方法时,必须等到任何事件处理程序的任何派生任务完成后,才能继续。
public void DoSomething()
{
// Expects any running tasks from OnEvent1(), OnEvent2(), OnEvent3()
// to be completed before proceeding.
}
public void OnEvent1()
{
Task.Factory
.StartNew(()=>{ /*Long running task*/ })
.ContinueWith(task=>{ /* Updates UI */ });
}
public void OnEvent2()
{
Task.Factory
.StartNew(()=>{ /*Long running task*/ })
.ContinueWith(task=>{ /* Updates UI */ });
}
public void OnEvent3()
{
Task.Factory
.StartNew(()=>{ /*Long running task*/ })
.ContinueWith(task=>{ /* Updates UI */ });
}
实际情况是:
- OnFetchData() => 生成任务。对此的所有后续调用都需要排队。
OnSyncSettings() => 生成任务。对此的所有后续调用都需要排队。
OnAutoBackup() => 同步方法。等待任何其他任务(例如,获取数据/同步设置)完成后再保存。
- OnFullBackup() => 同步方法。手动运行 FetchData() 和 SyncSettings(),等待完成,继续。
我的问题很简单:我该怎么做?
这种方法正确吗?
每个事件处理程序都会记住它的最后一个 .调用时,它将等待其列表中的所有任务完成后再继续。
对于同步方法,它需要等待所有任务(从每个事件处理程序)到
Task _lastEvent1Task;
public void OnEvent1()
{
// Wait for all tasks to complete before proceeding
if (_lastEvent1Task!=null)
_lastEvent1Task.Clear();
// Spawns new task
_lastEvent1Task = Task.Factory.StartNew(()=>{ });
}
public void OnEvent3()
{
// Wait for any running tasks to complete before proceeding
if (_lastEvent1Task != null) _lastEvent1Task.Wait();
if (_lastEvent2Task != null) _lastEvent2Task.Wait();
...
// Proceed
}
谢谢!
[编辑]
当 DoSomething() 正在等待并引发 Event1 时? 如果 DoSomething() 正在运行并引发事件怎么办?
OnEvents()
- 如果是第一个任务:生成任务并异步执行
- 如果之前的任务仍在运行,则排队/阻塞。关键部分。
-
假设:
- 这些事件通常不会多次引发。
- UI 应防止用户在运行时引发相同的事件。
DoSomething()(调用时)
- 假设:事件通知被禁用。
- 假设:不会有新事件排队。
- 预期:等到所有剩余的排队任务完成后再继续
- 预期:是同步调用,直到通过 执行才返回调用者
【问题讨论】:
-
如果可以选择,请转到 .net 4.5 以利用 async/await 的优点。它大大简化了这种代码。
-
@spender,感谢您的回复。不幸的是,4.5 不是我当前项目的选项。 :(
-
当
DoSomething()正在等待并引发Event1时应该发生什么?事件代码是否应该等到DoSomething()完成?还是应该DoSomething()也等待新事件?如果DoSomething()正在运行并引发事件怎么办? -
@svick 我已经用进一步的假设/预期行为更新了我的问题
-
async/await 现在可用于 .NET 4、Silverlight 4、Silverlight 5 和 Windows phone 7.1。在 NuGet 中搜索 Microsoft.Bcl.Async
标签: c# .net concurrency task-parallel-library