gpt4 book ai didi

c# - 使用 Task.Run 的后台线程

转载 作者:太空狗 更新时间:2023-10-29 23:06:42 26 4
gpt4 key购买 nike

当为 Oracle 数据库查询和 Active Directory 查询生成两个单独的任务然后等待两者时,您是否看到任何陷阱或问题。

下面是一个非常基本的精简示例。本质上,我们有一个员工对象,它是根据来自 AD 和 Oracle 数据库的信息片段创建的。 (顺序调用)

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-120 毫秒对比 200-250 毫秒)并且没有问题,但我不确定这是怎么回事在多核系统上扩展。我没有对 TPL 做过很多工作,但对这种方法很好奇。

最佳答案

我看不出有任何问题,这些是具有不同请求的不同服务,可能不共享任何状态。

但是,您应该意识到,在这两种情况下,您都占用了 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 并将“主”线程用于另一部分。

关于c# - 使用 Task.Run 的后台线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30720554/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com