C# 如何生成任务<;任务>;拆开
有人能解释一下这两种说法的区别吗C# 如何生成任务<;任务>;拆开,c#,.net,task-parallel-library,async-await,C#,.net,Task Parallel Library,Async Await,有人能解释一下这两种说法的区别吗 Task<Task> bTask = backup.BackupCurrentDatabaseAsync() .ContinueWith(_ => CompressArchiveAsync()); //unwrap the tasks to produce one entire task Task t = bTask.Unwrap(); Task bTask=backup.BackupCurrentDatabaseAsync() .C
Task<Task> bTask = backup.BackupCurrentDatabaseAsync()
.ContinueWith(_ => CompressArchiveAsync());
//unwrap the tasks to produce one entire task
Task t = bTask.Unwrap();
Task bTask=backup.BackupCurrentDatabaseAsync()
.ContinueWith(=>CompressArchiveAsync());
//展开任务以生成一个完整的任务
Task t=bTask.Unwrap();
vs
Task bTask=backup.BackupCurrentDatabaseAsync()
.ContinueWith(=>
{
CompressArchiveAsync();
});
//展开任务以生成一个完整的任务
Task t=bTask.Unwrap();
方法ExtractArchiveAsync()
,BackupCurrentDatabaseAsync()
,RestoreDatabaseAsync()
都返回一个任务
.ContinueWith(_ => CompressArchiveAsync());
这里,第一个延续返回一个任务
。然后,我可以Unwrap()
此任务以在结果(内部)任务上放置延续
第二个版本没有编译。这里唯一不同的是CompressArchiveAsync()
周围的大括号
我正在尝试访问结果(内部)任务
,以检查任务。状态
。如果使用第二种方法,Task.Status将报告BackupCurrentDatabaseAsync()
任务的结果 区别在于Lambda表达式语法
lambda有两种类型:表达式lambda和语句lambda。表达式lambda没有大括号并返回表达式的结果,而语句lambda有大括号包含零个或多个语句(其中一个可以是return
语句)
所以这个表达式Lambda:
_ => CompressArchiveAsync()
等同于此语句Lambda:
_ => { return CompressArchiveAsync(); }
所以,不同之处在于,在第一个继续中,您返回一个任务,但在第二个继续中,您没有返回,它只是一个无效的匿名委托。这就是为什么第一个continuation是一个任务
,而第二个continuation只是一个任务
.ContinueWith(_ => CompressArchiveAsync());
相当于:
.ContinueWith(_ =>
{
return CompressArchiveAsync();
});
请注意返回的
您的第二个代码段未编译,因为ContinueWith
不会返回任务
,而只返回任务
,并且没有任何可展开的内容
以下内容绑定到Func
(接受任务
并返回任务
的函数)
但以下内容实际上绑定到一个操作
(一个接受任务
但不返回任何内容的函数):
并且从不返回由CompressArchiveAsync
创建的对任务的引用。如果没有对它的引用,则无法检查任务的状态
请注意:
- 返回一个
任务
- 返回一个
任务
因此,您的ContinueWith(Func)
返回一个可以展开的Task
,但是ContinueWith(Action)
只返回一个Task在第一个示例中,您使用Func
调用ContinueWith
。因此,它将返回一个任务
。第二次尝试将调用带有操作的ContinueWith
重载,因为。。。这是一个动作,它不会返回任何东西。因此,它将返回一个简单的任务
,不带T
长注释,以显示4.5代码
.ContinueWith(_ => CompressArchiveAsync());
如果您可以迁移到.Net 4.5,那么您尝试编写的代码可以通过async/await以更紧凑的方式重写,async/await本质上是在内部实现所有代码:
async Task CompleteBackup()
{
await backup.BackupCurrentDatabaseAsync()
await CompressArchiveAsync());
await .....
}
边注:如果可能的话,考虑移动到4.5和异步/ AWAT。将产生更容易阅读的代码…不幸的是仍然在4!如何在4.5中实现上述功能?async
/wait
是C#5.0的主要功能。虽然它只在针对.NET 4.5时起到开箱即用的作用,但您可以使用异步目标包。感谢Alexei,如果我有与我的ContinueWith()相关联的TaskContinuationOptions
,这个方法会更详细吗?@Simon如果你需要对任务进行非常详细的控制,你可能仍然需要直接使用ContinueWith
和类似的调用。我没有这样做,所以没有直接的建议。@Simon:我建议你使用这个基于wait
的代码。通过安装,您可以将其与.NET 4.0桌面一起使用。使用await
,已经提供了所有适当的TaskContinuationOptions
,并且不需要那种级别的控制。@Stephen Cleary-谢谢,我将听取任务主管的建议:async/await是C#5特性(它的目标是.NET4.5+,但正如StephenCleary所提到的,它也可以与该包一起在.NET4.0上使用)
async Task CompleteBackup()
{
await backup.BackupCurrentDatabaseAsync()
await CompressArchiveAsync());
await .....
}