我有一个做同步事情的简单类,
public static class Synchronous
{
public static void DoTheWholeThing()
{
AStuff aStuff;
using (var a = new A())
{
aStuff = a.GetStuff();
}
BStuff bStuff;
using (var b = new B())
{
bStuff = b.GetStuff();
}
var combination = CombineStuff(aStuff, bStuff);
}
private static Combination CombineStuff(AStuff aStuff, BStuff bStuff)
{
//// Magic Here
}
}
显然,这段代码没有完全定义,但它确实说明了我的问题。
现在,类 A
和 B
两者都负责从不同的远程源检索数据。因此,A
的开发者和 B
已经实现了称为 GetStuffAsync
的异步入口点返回 Task<AStuff>
和 Task<BStuff>
分别。
我想最大限度地利用异步方法并同时调用它们,这样我就可以减少代码的总体等待时间。
到目前为止,这是我编造的内容。
public static class Asynchronous
{
public async static Task DoTheWholeThing(CancellationToken cancellationToken)
{
var getAStuffTask = new Func<Task<AStuff>>(
async () =>
{
using (var a = new A())
{
return await a.GetStuffAsync(cancellationToken);
}
})();
var getBStuffTask = new Func<Task<BStuff>>(
async () =>
{
using (var b = new B())
{
return await b.GetStuffAsync(cancellationToken);
}
})();
var combination = CombineStuff(
await getAStuffTask,
await getBStuffTask);
}
private Combination CombineStuff(AStuff aStuff, BStuff bStuff)
{
//// Magic Here
}
}
除了这段代码看起来很像 javascript 模块模式之外,这是正确的方法吗?我认为我不应该使用 Task.Run
因为此代码是 clearly not CPU bound .
似乎有点“笨拙”,我需要实例化类型化委托(delegate)来执行此操作。有没有更好的办法?
编辑
继两个很好的答案之后,我在命名函数和延续之间进退两难。
最佳答案
当您简单地将匿名方法提取到命名方法中时,代码会变得非常简单:
public async static Task DoTheWholeThing(CancellationToken cancellationToken)
{
var getAStuffTask = GetAStuffAsync(cancellationToken);
var getBStuffTask = GetBStuffAsync(cancellationToken);
var combination = CombineStuff(
await getAStuffTask,
await getBStuffTask);
}
private static async Task<AStuff> GetAStuffAsync(CancellationToken cancellationToken)
{
using (var a = new A())
{
return await a.GetStuffAsync(cancellationToken);
}
}
private static async Task<BStuff> GetBStuffAsync(CancellationToken cancellationToken)
{
using (var b = new B())
{
return await b.GetStuffAsync(cancellationToken);
}
}
就是说,如果您真的想坚持使用匿名方法,您可以创建一个辅助方法,它允许泛型类型推断和 lambda 隐式确定委托(delegate)的类型:
public async static Task DoTheWholeThing(CancellationToken cancellationToken)
{
var getAStuffTask = Start(async () =>
{
using (var a = new A())
{
return await a.GetStuffAsync(cancellationToken);
}
});
var getBStuffTask = Start(async () =>
{
using (var b = new B())
{
return await b.GetStuffAsync(cancellationToken);
}
});
var combination = CombineStuff(
await getAStuffTask,
await getBStuffTask);
}
public static Task<T> Start<T>(Func<Task<T>> asyncOperation)
{
return asyncOperation();
}
关于c# - 匿名异步,怎样才是正确的做法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32378681/