在为Oracle数据库查询和Active Directory查询生成两个单独的任务然后等待这两个任务时,您是否看到任何陷阱或问题。
下面是一个非常基本的剥离示例。基本上,我们有一个员工对象,它是从AD和Oracle DB的信息中创建的。 (顺序调用)
var partialEmployeeA=ActiveDirectoryLookup(employeeID);
var partialEmployeeB=OracleDBLookup(employeeID);
var finalEmployee=Merge(partialEmployeeA,partialEmployeeB);
此时,Employee
对象已创建并从两个查询拼凑在一起,可以使用。这没有问题,但如果这些调用中的每一个都是它自己的任务,你会从扩展视角看到任何问题吗? (不包括任何其他明显的代码问题)
Employee partialEmployeeA;
Employee partialEmployeeB;
var t1 = Task.Run(() => {
partialEmployeeA=ActiveDirectoryLookup(employeeID);
});
var t2 = Task.Run(() => {
partialEmployeeB=OracleDBLookup(employeeID);
});,
Task.WaitAll(t1, t2);
var finalEmployee=Merge(partialEmployeeA,partialEmployeeB);
我用秒表类进行了一些测试,每次Task
版本恢复得更快(平均值:100-120ms vs 200-250ms)并没有问题,但不确定这是如何缩放的多核系统。我没有对TPL做过很多,但对这种方法很好奇。
答案 0 :(得分:6)
我没有看到任何问题,这些是不同的服务,可能不会分享任何州。
但是,您应该意识到,在这两种情况下,您将占用3个在整个异步(I / O)操作中阻塞的线程。
通过利用多个线程并行执行这些操作会更快。但它实际上更具可扩展性。
要做到这一点"对"在不阻塞线程和耗尽资源的情况下,您需要将这些操作视为真正的异步,而不仅仅是在后台线程上:
var partialEmployeeATask = ActiveDirectoryLookupAsync(employeeID);
var partialEmployeeBTask = OracleDBLookupAsync(employeeID);
await Task.WhenAll(partialEmployeeATask, partialEmployeeBTask)
var finalEmployee = Merge(await partialEmployeeATask, await partialEmployeeBTask);
这需要更改API以支持某种形式的异步请求。如果API不在您的控制之下,则可能是一个问题。如果不能这样做,至少只使用Task.Run
一次并使用" main"线程到另一部分。