gpt4 book ai didi

c# - 关于从 Parallel.ForEach() 中调用外部方法是否有任何特殊规则或注意事项?

转载 作者:太空宇宙 更新时间:2023-11-03 12:15:46 25 4
gpt4 key购买 nike

关于从 Parallel.ForEach() 中调用外部方法是否有任何特殊规则或注意事项?我想确保避免任何古怪的多线程问题。考虑以下 Parallel.ForEach() 例程:

public void GetGroupUsers()
{
Parallel.ForEach(
groups.ToList(),
new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount },
group =>
{
//get associated user id's by group name
userGuids = GetUserGuidsForGroup(1);

//if no group-users then continue
if (userGuids == null) return;

//update group user map
foreach (var userGuid in userGuids)
groupUserMap.Add(new KeyValuePair<Guid, Guid>(group.Key, userGuid));
});
}

private List<Guid> GetUserGuidsForGroup(int groupNumber)
{
var userGuids = new List<Guid>();
//do a repo lookup of user guids for the groupNumber parameter and add to list
return userGuids;
}

最佳答案

Are there any special rules or caveats about calling outside methods from within a Parallel.ForEach()?

编写简单的多线程应用程序时,规则/注意事项保持不变。只是这里的线程是通过池提供的,而不是由用户创建的。当您调用 .Net 框架 api 时,您仍在调用外部/框架方法。在 .Net 框架 api 调用的情况下,您只需要确保每个线程都有自己唯一的对象来进行调用(因此线程安全),或者共享对象在线程安全区域中进行方法调用。专注于 Write 调用(它改变对象的状态)而不是 Read 调用。列出几个重要的:

  1. 避免竞争条件,不要在没有使用InterlockedLock等构造创建线程安全区域的情况下编写/更新共享/全局/静态变量信号量互斥量
  2. 尝试使用线程安全/并发集合,因为它们做得更好,因为您无需担心显式同步
  3. 读取通常是线程安全的,但写入不是,并且可能导致竞争条件(更常见)、死锁(使用并发集合很容易避免所有这些)
  4. 使用类似ThreadLocal/ThreadStatic的东西,要小心,因为这里要处理number_of_threads != number_of_Elements,这意味着同一个线程可以/将用于多次迭代,因此它会保留您可能不会想到的本地状态,因此它可能需要显式重置此类变量的状态。这通常会导致问题。
  5. 区分 IO 调用和计算调用,因为 Parallel API 不是 IO 绑定(bind)调用的糟糕选择,Async-Await 是更好的选择

关于c# - 关于从 Parallel.ForEach() 中调用外部方法是否有任何特殊规则或注意事项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49851437/

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