Jas*_*aat 7 c# multitasking task-parallel-library
我有一个有两个方法的类,Load()和Process().我希望能够将这些单独作为后台任务或按顺序运行.我喜欢ContinueWith()语法,但我无法让它工作.我必须在我继续的方法上获取一个Task参数,并且在初始方法上不能有Task参数.
我想在没有lambda表达式的情况下做到这一点,但我是不是使用它们,强制在其中一个方法上创建任务参数,或者创建第三个方法LoadAndProcess()?
void Run()
{
// doesn't work, but I'd like to do it
//Task.Factory.StartNew(MethodNoArguments).ContinueWith(MethodNoArguments);
Console.WriteLine("ContinueWith");
Task.Factory.StartNew(MethodNoArguments).ContinueWith(MethodWithTaskArgument).Wait();
Console.WriteLine("Lambda");
Task.Factory.StartNew(() => { MethodNoArguments(); MethodNoArguments(); }).Wait();
Console.WriteLine("ContinueWith Lambda");
Task.Factory.StartNew(MethodNoArguments).ContinueWith(x => {
MethodNoArguments();
}).Wait();
}
void MethodNoArguments()
{
Console.WriteLine("MethodNoArguments()");
}
void MethodWithTaskArgument(Task t = null)
{
Console.WriteLine("MethodWithTaskArgument()");
}
Run Code Online (Sandbox Code Playgroud)
svi*_*ick 14
在所有重载中ContinueWith()
,第一个参数是一个带有a的委托Task
,因此您无法将无参数委托传递给它.
我认为使用lambdas非常好,并且不会影响可读性.并且代码中的lambda不必要地冗长:
Task.Factory.StartNew(MethodNoArguments).ContinueWith(_ => MethodNoArguments())
Run Code Online (Sandbox Code Playgroud)
或者,正如Cory Carson在评论中指出的那样,你可以写一个扩展方法:
public static Task ContinueWith(this Task task, Action action)
{
return task.ContinueWith(_ => action());
}
Run Code Online (Sandbox Code Playgroud)
使用多个延续时编写干净的代码并不是那么容易,尽管您可以遵循一些规则来使代码更干净:
您可以将代码更改为这样的内容,这样稍微简洁一些:
var call1=Task.Factory.StartNew(()=>MethodNoArguments());
var call2 = call1.ContinueWith(_ => MethodNoArguments());
call2.Wait();
Run Code Online (Sandbox Code Playgroud)
甚至
var call1 = Task.Factory.StartNew<Task>(MethodNoArguments);
var call2 = call1.Then(MethodNoArguments);
call2.Wait();
Run Code Online (Sandbox Code Playgroud)
Stephen Toub 在使用任务处理异步操作序列中讨论了 Then 扩展和其他清理代码的方法
这个问题在 C# 4 中得到了很好的解决。 在 C# 5 中,您可以使用 async/await 关键字创建看起来像原始同步版本的干净代码,例如:
static async Task Run()
{
await MethodNoArguments();
await MethodNoArguments();
}
static async Task MethodNoArguments()
{
await Task.Run(()=>Console.WriteLine("MethodNoArguments()"));
}
Run Code Online (Sandbox Code Playgroud)
Visual Studio 11 和 .NET 4.5 具有 Go Live 许可证,因此您可能可以立即开始使用它们。
您可以在 C# 4 中使用 Async CTP 来实现相同的结果。您可以在生产中使用 Async CTP,因为它具有上线许可证。缺点是当您迁移到 .NET 4.5 时,由于 CTP 和 .NET 4.5 之间的差异(例如,CTP 具有 TaskEx.Run 而不是 Task.Run),您必须对代码进行一些小的更改。
归档时间: |
|
查看次数: |
13434 次 |
最近记录: |