gpt4 book ai didi

c# - 锁定并完成所有工作,还是仅在必要时松开并抓取?

转载 作者:太空宇宙 更新时间:2023-11-03 13:16:23 24 4
gpt4 key购买 nike

这两种选择中哪一种更好?

在循环外锁定?

lock (_workLock)
{
foreach (var resultObject in getObjectTask.Result)
{
foreach (var key in resultObject.Keys)
{
string value = resultObject.GetValue(key);
_lockedObject.DoSomething(key, value);
}
}
}

还是仅在访问锁定对象时才锁定?

foreach (var resultObject in getObjectTask.Result)
{
foreach (var key in resultObject.Keys)
{
string value = resultObject.GetValue(key);
lock (_workLock)
_lockedObject.DoSomething(key, value);
}
}

可能有 5-10 个并发操作想要大致同时执行此操作。这是周围的代码:

var tasks =
from provider in _objectProviders
select Task.Factory.StartNew(() => provider.Objects)
.ContinueWith(getObjectTask =>
{
// One of the operation bodies from above would go here
});

var taskList = Task.WhenAll(tasks);
taskList.Wait();

// Use results from operations here

编辑:这不是真正的答案,所以我没有将其作为答案发布,但是在评论部分输入之后,我重构了我的代码,现在我根本不再需要锁了:

var tasks =
(from provider in _objectProviders
select Task.Factory.StartNew(() => provider.Objects)).ToList();

while (tasks.Count > 0)
{
int completedTask = Task.WaitAny(tasks.ToArray<Task>());
var task = tasks[completedTask];
var objects = task.Result;

foreach (var resultObject in objects)
{
foreach (var key in resultObject.Keys)
{
string value = resultObject.GetValue(key);
_unlockedObject.DoSomething(key, value);
}
}

tasks.RemoveAt(completedTask);
}

最佳答案

视情况而定!

哪个更好 100% 取决于您的任务在做什么。

在循环内获取锁意味着您要浪费大量时间来获取和释放锁。但是,如果您的大部分时间都花在做非锁定并行事情上,它可以释放足够多的锁以获得更多并行性。

在循环顶部获取锁会阻止并行性,但会节省锁定,这与您的操作相比可能代价高昂。

所有你能做的就是看看你的分析器,找出最适合你的情况。作为引用,如果没有争用,现代硬件上的锁需要大约 100-150 次操作才能锁定/解锁(这是粗略的经验法则,而不是硬设置值)。

考虑第三种选择,它是两者的混合体:执行所有并行操作,然后批量处理串行操作。也许每 10 个对象,捕获锁并快速完成所有的串行工作。这让您可以两全其美

关于c# - 锁定并完成所有工作,还是仅在必要时松开并抓取?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25933832/

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